Merge branch 'master' into stable-4.2
Change-Id: Ia92c91e1226da7d6455ab14f1e255a1546f8f357 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
This commit is contained in:
commit
edec10dc39
|
@ -209,7 +209,7 @@ public void testInitialClone_Loose() throws Exception {
|
|||
}
|
||||
|
||||
assertTrue(dst.hasObject(A_txt));
|
||||
assertEquals(B, dst.getRef(master).getObjectId());
|
||||
assertEquals(B, dst.exactRef(master).getObjectId());
|
||||
fsck(dst, B);
|
||||
|
||||
List<AccessEvent> loose = getRequests(loose(remoteURI, A_txt));
|
||||
|
@ -234,7 +234,7 @@ public void testInitialClone_Packed() throws Exception {
|
|||
}
|
||||
|
||||
assertTrue(dst.hasObject(A_txt));
|
||||
assertEquals(B, dst.getRef(master).getObjectId());
|
||||
assertEquals(B, dst.exactRef(master).getObjectId());
|
||||
fsck(dst, B);
|
||||
|
||||
List<AccessEvent> req;
|
||||
|
|
|
@ -225,7 +225,7 @@ public void testInitialClone_Small() throws Exception {
|
|||
}
|
||||
|
||||
assertTrue(dst.hasObject(A_txt));
|
||||
assertEquals(B, dst.getRef(master).getObjectId());
|
||||
assertEquals(B, dst.exactRef(master).getObjectId());
|
||||
fsck(dst, B);
|
||||
|
||||
List<AccessEvent> loose = getRequests(loose(remoteURI, A_txt));
|
||||
|
@ -253,7 +253,7 @@ public void testInitialClone_Packed() throws Exception {
|
|||
}
|
||||
|
||||
assertTrue(dst.hasObject(A_txt));
|
||||
assertEquals(B, dst.getRef(master).getObjectId());
|
||||
assertEquals(B, dst.exactRef(master).getObjectId());
|
||||
fsck(dst, B);
|
||||
|
||||
List<AccessEvent> req;
|
||||
|
|
|
@ -164,8 +164,8 @@ public void testPush_CreateBranch() throws Exception {
|
|||
}
|
||||
|
||||
assertTrue(remoteRepository.hasObject(Q_txt));
|
||||
assertNotNull("has " + dstName, remoteRepository.getRef(dstName));
|
||||
assertEquals(Q, remoteRepository.getRef(dstName).getObjectId());
|
||||
assertNotNull("has " + dstName, remoteRepository.exactRef(dstName));
|
||||
assertEquals(Q, remoteRepository.exactRef(dstName).getObjectId());
|
||||
fsck(remoteRepository, Q);
|
||||
|
||||
List<AccessEvent> requests = getRequests();
|
||||
|
|
|
@ -296,7 +296,7 @@ public void testInitialClone_Small() throws Exception {
|
|||
}
|
||||
|
||||
assertTrue(dst.hasObject(A_txt));
|
||||
assertEquals(B, dst.getRef(master).getObjectId());
|
||||
assertEquals(B, dst.exactRef(master).getObjectId());
|
||||
fsck(dst, B);
|
||||
|
||||
List<AccessEvent> requests = getRequests();
|
||||
|
@ -337,7 +337,7 @@ public void testFetch_FewLocalCommits() throws Exception {
|
|||
} finally {
|
||||
t.close();
|
||||
}
|
||||
assertEquals(B, dst.getRepository().getRef(master).getObjectId());
|
||||
assertEquals(B, dst.getRepository().exactRef(master).getObjectId());
|
||||
List<AccessEvent> cloneRequests = getRequests();
|
||||
|
||||
// Only create a few new commits.
|
||||
|
@ -358,7 +358,7 @@ public void testFetch_FewLocalCommits() throws Exception {
|
|||
} finally {
|
||||
t.close();
|
||||
}
|
||||
assertEquals(Z, dst.getRepository().getRef(master).getObjectId());
|
||||
assertEquals(Z, dst.getRepository().exactRef(master).getObjectId());
|
||||
|
||||
List<AccessEvent> requests = getRequests();
|
||||
requests.removeAll(cloneRequests);
|
||||
|
@ -400,7 +400,7 @@ public void testFetch_TooManyLocalCommits() throws Exception {
|
|||
} finally {
|
||||
t.close();
|
||||
}
|
||||
assertEquals(B, dst.getRepository().getRef(master).getObjectId());
|
||||
assertEquals(B, dst.getRepository().exactRef(master).getObjectId());
|
||||
List<AccessEvent> cloneRequests = getRequests();
|
||||
|
||||
// Force enough into the local client that enumeration will
|
||||
|
@ -424,7 +424,7 @@ public void testFetch_TooManyLocalCommits() throws Exception {
|
|||
} finally {
|
||||
t.close();
|
||||
}
|
||||
assertEquals(Z, dst.getRepository().getRef(master).getObjectId());
|
||||
assertEquals(Z, dst.getRepository().exactRef(master).getObjectId());
|
||||
|
||||
List<AccessEvent> requests = getRequests();
|
||||
requests.removeAll(cloneRequests);
|
||||
|
@ -579,8 +579,8 @@ public void testPush_CreateBranch() throws Exception {
|
|||
}
|
||||
|
||||
assertTrue(remoteRepository.hasObject(Q_txt));
|
||||
assertNotNull("has " + dstName, remoteRepository.getRef(dstName));
|
||||
assertEquals(Q, remoteRepository.getRef(dstName).getObjectId());
|
||||
assertNotNull("has " + dstName, remoteRepository.exactRef(dstName));
|
||||
assertEquals(Q, remoteRepository.exactRef(dstName).getObjectId());
|
||||
fsck(remoteRepository, Q);
|
||||
|
||||
final ReflogReader log = remoteRepository.getReflogReader(dstName);
|
||||
|
@ -657,8 +657,8 @@ public void testPush_ChunkedEncoding() throws Exception {
|
|||
}
|
||||
|
||||
assertTrue(remoteRepository.hasObject(Q_bin));
|
||||
assertNotNull("has " + dstName, remoteRepository.getRef(dstName));
|
||||
assertEquals(Q, remoteRepository.getRef(dstName).getObjectId());
|
||||
assertNotNull("has " + dstName, remoteRepository.exactRef(dstName));
|
||||
assertEquals(Q, remoteRepository.exactRef(dstName).getObjectId());
|
||||
fsck(remoteRepository, Q);
|
||||
|
||||
List<AccessEvent> requests = getRequests();
|
||||
|
|
|
@ -241,6 +241,17 @@ public static void deleteTrashFile(final Repository db,
|
|||
FileUtils.delete(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param db
|
||||
* the repository
|
||||
* @param link
|
||||
* the path of the symbolic link to create
|
||||
* @param target
|
||||
* the target of the symbolic link
|
||||
* @return the path to the symbolic link
|
||||
* @throws Exception
|
||||
* @since 4.2
|
||||
*/
|
||||
public static Path writeLink(Repository db, String link,
|
||||
String target) throws Exception {
|
||||
return FileUtils.createSymLink(new File(db.getWorkTree(), link),
|
||||
|
|
|
@ -91,7 +91,10 @@ public abstract class LocalDiskRepositoryTestCase {
|
|||
/** A fake (but stable) identity for committer fields in the test. */
|
||||
protected PersonIdent committer;
|
||||
|
||||
/** A {@link SystemReader} used to coordinate time, envars, etc. */
|
||||
/**
|
||||
* A {@link SystemReader} used to coordinate time, envars, etc.
|
||||
* @since 4.2
|
||||
*/
|
||||
protected MockSystemReader mockSystemReader;
|
||||
|
||||
private final List<Repository> toClose = new ArrayList<Repository>();
|
||||
|
|
|
@ -151,6 +151,7 @@ public long getCurrentTime() {
|
|||
*
|
||||
* @param secDelta
|
||||
* number of seconds to add to the current time.
|
||||
* @since 4.2
|
||||
*/
|
||||
public void tick(final int secDelta) {
|
||||
now += secDelta * 1000L;
|
||||
|
|
|
@ -108,6 +108,17 @@ protected File writeTrashFile(final String name, final String data)
|
|||
return JGitTestUtil.writeTrashFile(db, name, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a symbolic link
|
||||
*
|
||||
* @param link
|
||||
* the path of the symbolic link to create
|
||||
* @param target
|
||||
* the target of the symbolic link
|
||||
* @return the path to the symbolic link
|
||||
* @throws Exception
|
||||
* @since 4.2
|
||||
*/
|
||||
protected Path writeLink(final String link, final String target)
|
||||
throws Exception {
|
||||
return JGitTestUtil.writeLink(db, link, target);
|
||||
|
@ -271,6 +282,19 @@ public static String lookup(Object l, String nameTemplate,
|
|||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces '\' by '/'
|
||||
*
|
||||
* @param str
|
||||
* the string in which backslashes should be replaced
|
||||
* @return the resulting string with slashes
|
||||
* @since 4.2
|
||||
*/
|
||||
public static String slashify(String str) {
|
||||
str = str.replace('\\', '/');
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits until it is guaranteed that a subsequent file modification has a
|
||||
* younger modification timestamp than the modification timestamp of the
|
||||
|
|
|
@ -175,6 +175,7 @@ public TestRepository(R db, RevWalk rw) throws IOException {
|
|||
* the MockSystemReader to use for clock and other system
|
||||
* operations.
|
||||
* @throws IOException
|
||||
* @since 4.2
|
||||
*/
|
||||
public TestRepository(R db, RevWalk rw, MockSystemReader reader)
|
||||
throws IOException {
|
||||
|
@ -203,7 +204,10 @@ public Git git() {
|
|||
return git;
|
||||
}
|
||||
|
||||
/** @return current date. */
|
||||
/**
|
||||
* @return current date.
|
||||
* @since 4.2
|
||||
*/
|
||||
public Date getDate() {
|
||||
return new Date(mockSystemReader.getCurrentTime());
|
||||
}
|
||||
|
|
|
@ -15,12 +15,6 @@
|
|||
<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/>
|
||||
<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/>
|
||||
<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit4"/>
|
||||
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7" path="1" type="4"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry id="org.eclipse.jdt.launching.classpathentry.defaultClasspath"> <memento exportedEntriesOnly="false" project="org.eclipse.jgit.pgm.test"/> </runtimeClasspathEntry> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry path="3" projectName="org.eclipse.jgit.java7" type="1"/> "/>
|
||||
</listAttribute>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value=""/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.eclipse.jgit.pgm.test"/>
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7" path="1" type="4"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry id="org.eclipse.jdt.launching.classpathentry.defaultClasspath"> <memento exportedEntriesOnly="false" project="org.eclipse.jgit.pgm.test"/> </runtimeClasspathEntry> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry path="3" projectName="org.eclipse.jgit.java7" type="1"/> "/>
|
||||
</listAttribute>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
|
||||
|
|
|
@ -198,7 +198,8 @@ public void testCheckoutOrphan() throws Exception {
|
|||
|
||||
assertStringArrayEquals("Switched to a new branch 'new_branch'",
|
||||
execute("git checkout --orphan new_branch"));
|
||||
assertEquals("refs/heads/new_branch", db.getRef("HEAD").getTarget().getName());
|
||||
assertEquals("refs/heads/new_branch",
|
||||
db.exactRef("HEAD").getTarget().getName());
|
||||
RevCommit commit = git.commit().setMessage("orphan commit").call();
|
||||
assertEquals(0, commit.getParentCount());
|
||||
}
|
||||
|
|
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* Copyright (C) 2015, Kaloyan Raev <kaloyan.r@zend.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.pgm;
|
||||
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jgit.api.Git;
|
||||
import org.eclipse.jgit.lib.CLIRepositoryTestCase;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.lib.StoredConfig;
|
||||
import org.eclipse.jgit.transport.RefSpec;
|
||||
import org.eclipse.jgit.transport.RemoteConfig;
|
||||
import org.eclipse.jgit.transport.URIish;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class RemoteTest extends CLIRepositoryTestCase {
|
||||
|
||||
private StoredConfig config;
|
||||
|
||||
private RemoteConfig remote;
|
||||
|
||||
@Before
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
// create another repository
|
||||
Repository remoteRepository = createWorkRepository();
|
||||
|
||||
// set it up as a remote to this repository
|
||||
config = db.getConfig();
|
||||
remote = new RemoteConfig(config, "test");
|
||||
remote.addFetchRefSpec(
|
||||
new RefSpec("+refs/heads/*:refs/remotes/test/*"));
|
||||
URIish uri = new URIish(
|
||||
remoteRepository.getDirectory().toURI().toURL());
|
||||
remote.addURI(uri);
|
||||
remote.update(config);
|
||||
config.save();
|
||||
|
||||
Git.wrap(remoteRepository).commit().setMessage("initial commit").call();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testList() throws Exception {
|
||||
assertArrayEquals(new String[] { remote.getName(), "" },
|
||||
execute("git remote"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVerboseList() throws Exception {
|
||||
assertArrayEquals(
|
||||
new String[] {
|
||||
String.format("%s\t%s (fetch)", remote.getName(),
|
||||
remote.getURIs().get(0)),
|
||||
String.format("%s\t%s (push)", remote.getName(),
|
||||
remote.getURIs().get(0)),
|
||||
"" },
|
||||
execute("git remote -v"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAdd() throws Exception {
|
||||
assertArrayEquals(new String[] { "" },
|
||||
execute("git remote add second git://test.com/second"));
|
||||
|
||||
List<RemoteConfig> remotes = RemoteConfig.getAllRemoteConfigs(config);
|
||||
assertEquals(2, remotes.size());
|
||||
assertEquals("second", remotes.get(0).getName());
|
||||
assertEquals("test", remotes.get(1).getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemove() throws Exception {
|
||||
assertArrayEquals(new String[] { "" },
|
||||
execute("git remote remove test"));
|
||||
|
||||
assertTrue(RemoteConfig.getAllRemoteConfigs(config).isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetUrl() throws Exception {
|
||||
assertArrayEquals(new String[] { "" },
|
||||
execute("git remote set-url test git://test.com/test"));
|
||||
|
||||
RemoteConfig result = new RemoteConfig(config, "test");
|
||||
assertEquals("test", result.getName());
|
||||
assertArrayEquals(new URIish[] { new URIish("git://test.com/test") },
|
||||
result.getURIs().toArray());
|
||||
assertTrue(result.getPushURIs().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetUrlPush() throws Exception {
|
||||
assertArrayEquals(new String[] { "" },
|
||||
execute("git remote set-url --push test git://test.com/test"));
|
||||
|
||||
RemoteConfig result = new RemoteConfig(config, "test");
|
||||
assertEquals("test", result.getName());
|
||||
assertEquals(remote.getURIs(), result.getURIs());
|
||||
assertArrayEquals(new URIish[] { new URIish("git://test.com/test") },
|
||||
result.getPushURIs().toArray());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdate() throws Exception {
|
||||
assertArrayEquals(new String[] {
|
||||
"From " + remote.getURIs().get(0).toString(),
|
||||
" * [new branch] master -> test/master", "", "" },
|
||||
execute("git remote update test"));
|
||||
}
|
||||
|
||||
}
|
|
@ -67,7 +67,7 @@ public void testResetSelf() throws Exception {
|
|||
assertStringArrayEquals("",
|
||||
execute("git reset --hard " + commit.getId().name()));
|
||||
assertEquals(commit.getId(),
|
||||
git.getRepository().getRef("HEAD").getObjectId());
|
||||
git.getRepository().exactRef("HEAD").getObjectId());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -77,7 +77,7 @@ public void testResetPrevious() throws Exception {
|
|||
assertStringArrayEquals("",
|
||||
execute("git reset --hard " + commit.getId().name()));
|
||||
assertEquals(commit.getId(),
|
||||
git.getRepository().getRef("HEAD").getObjectId());
|
||||
git.getRepository().exactRef("HEAD").getObjectId());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -86,7 +86,7 @@ public void testResetEmptyPath() throws Exception {
|
|||
assertStringArrayEquals("",
|
||||
execute("git reset --hard " + commit.getId().name() + " --"));
|
||||
assertEquals(commit.getId(),
|
||||
git.getRepository().getRef("HEAD").getObjectId());
|
||||
git.getRepository().exactRef("HEAD").getObjectId());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -119,7 +119,7 @@ private void resetPath(boolean useDoubleDash) throws Exception {
|
|||
(useDoubleDash) ? " --" : "");
|
||||
assertStringArrayEquals("", execute(cmd));
|
||||
assertEquals(commit.getId(),
|
||||
git.getRepository().getRef("HEAD").getObjectId());
|
||||
git.getRepository().exactRef("HEAD").getObjectId());
|
||||
|
||||
org.eclipse.jgit.api.Status status = git.status().call();
|
||||
// assert that file a is unstaged
|
||||
|
|
|
@ -42,13 +42,14 @@
|
|||
*/
|
||||
package org.eclipse.jgit.pgm;
|
||||
|
||||
import static org.eclipse.jgit.lib.Constants.MASTER;
|
||||
import static org.eclipse.jgit.lib.Constants.R_HEADS;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.jgit.api.Git;
|
||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||
import org.eclipse.jgit.lib.CLIRepositoryTestCase;
|
||||
import org.eclipse.jgit.lib.Constants;
|
||||
import org.eclipse.jgit.revwalk.RevCommit;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -254,7 +255,7 @@ private void mergeTestBranchInMaster(Git git, RevCommit aCommit)
|
|||
}
|
||||
|
||||
private void detachHead(Git git) throws IOException, GitAPIException {
|
||||
String commitId = db.getRef(Constants.MASTER).getObjectId().name();
|
||||
String commitId = db.exactRef(R_HEADS + MASTER).getObjectId().name();
|
||||
git.checkout().setName(commitId).call();
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ org.eclipse.jgit.pgm.MergeBase
|
|||
org.eclipse.jgit.pgm.Push
|
||||
org.eclipse.jgit.pgm.ReceivePack
|
||||
org.eclipse.jgit.pgm.Reflog
|
||||
org.eclipse.jgit.pgm.Remote
|
||||
org.eclipse.jgit.pgm.Repo
|
||||
org.eclipse.jgit.pgm.Reset
|
||||
org.eclipse.jgit.pgm.RevList
|
||||
|
|
|
@ -128,6 +128,7 @@ metaVar_user=USER
|
|||
metaVar_version=VERSION
|
||||
mostCommonlyUsedCommandsAre=The most commonly used commands are:
|
||||
needApprovalToDestroyCurrentRepository=Need approval to destroy current repository
|
||||
needSingleRevision=Needed a single revision
|
||||
noGitRepositoryConfigured=No Git repository configured.
|
||||
noNamesFound=No names found, cannot describe anything.
|
||||
noSuchFile=no such file: {0}
|
||||
|
@ -142,6 +143,7 @@ notAJgitCommand={0} is not a jgit command
|
|||
notARevision=Not a revision: {0}
|
||||
notATree={0} is not a tree
|
||||
notAValidRefName={0} is not a valid ref name
|
||||
notAValidCommitName={0} is not a valid commit name
|
||||
notAnIndexFile={0} is not an index file
|
||||
notAnObject={0} is not an object
|
||||
notFound=!! NOT FOUND !!
|
||||
|
@ -186,6 +188,7 @@ treeIsRequired=argument tree is required
|
|||
tooManyRefsGiven=Too many refs given
|
||||
unknownIoErrorStdout=An unknown I/O error occurred on standard output
|
||||
unknownMergeStrategy=unknown merge strategy {0} specified
|
||||
unknownSubcommand=Unknown subcommand: {0}
|
||||
unmergedPaths=Unmerged paths:
|
||||
unsupportedOperation=Unsupported operation: {0}
|
||||
untrackedFiles=Untracked files:
|
||||
|
@ -220,6 +223,7 @@ usage_MergeBase=Find as good common ancestors as possible for a merge
|
|||
usage_MergesTwoDevelopmentHistories=Merges two development histories
|
||||
usage_ReadDirCache= Read the DirCache 100 times
|
||||
usage_RebuildCommitGraph=Recreate a repository from another one's commit graph
|
||||
usage_Remote=Manage set of tracked repositories
|
||||
usage_RepositoryToReadFrom=Repository to read from
|
||||
usage_RepositoryToReceiveInto=Repository to receive into
|
||||
usage_RevList=List commit objects in reverse chronological order
|
||||
|
@ -327,6 +331,7 @@ usage_performFsckStyleChecksOnReceive=perform fsck style checks on receive
|
|||
usage_portNumberToListenOn=port number to listen on
|
||||
usage_printOnlyBranchesThatContainTheCommit=print only branches that contain the commit
|
||||
usage_pruneStaleTrackingRefs=prune stale tracking refs
|
||||
usage_pushUrls=push URLs are manipulated
|
||||
usage_quiet=don't show progress messages
|
||||
usage_recordChangesToRepository=Record changes to the repository
|
||||
usage_recurseIntoSubtrees=recurse into subtrees
|
||||
|
|
|
@ -154,10 +154,14 @@ protected void run() throws Exception {
|
|||
startBranch = Constants.HEAD;
|
||||
Ref startRef = db.getRef(startBranch);
|
||||
ObjectId startAt = db.resolve(startBranch + "^0"); //$NON-NLS-1$
|
||||
if (startRef != null)
|
||||
if (startRef != null) {
|
||||
startBranch = startRef.getName();
|
||||
else
|
||||
} else if (startAt != null) {
|
||||
startBranch = startAt.name();
|
||||
} else {
|
||||
throw die(MessageFormat.format(
|
||||
CLIText.get().notAValidCommitName, startBranch));
|
||||
}
|
||||
startBranch = Repository.shortenRefName(startBranch);
|
||||
String newRefName = newHead;
|
||||
if (!newRefName.startsWith(Constants.R_HEADS))
|
||||
|
@ -249,7 +253,7 @@ private void delete(boolean force) throws IOException {
|
|||
String current = db.getBranch();
|
||||
ObjectId head = db.resolve(Constants.HEAD);
|
||||
for (String branch : branches) {
|
||||
if (current.equals(branch)) {
|
||||
if (branch.equals(current)) {
|
||||
throw die(MessageFormat.format(CLIText.get().cannotDeleteTheBranchWhichYouAreCurrentlyOn, branch));
|
||||
}
|
||||
RefUpdate update = db.updateRef((remote ? Constants.R_REMOTES
|
||||
|
|
|
@ -96,6 +96,9 @@ protected void run() throws NoHeadException, NoMessageException,
|
|||
commitCmd.setAmend(amend);
|
||||
commitCmd.setAll(all);
|
||||
Ref head = db.getRef(Constants.HEAD);
|
||||
if (head == null) {
|
||||
throw die(CLIText.get().onBranchToBeBorn);
|
||||
}
|
||||
RevCommit commit;
|
||||
try {
|
||||
commit = commitCmd.call();
|
||||
|
|
|
@ -120,7 +120,7 @@ protected void run() throws Exception {
|
|||
throw die(MessageFormat.format(
|
||||
CLIText.get().refDoesNotExistOrNoCommit, ref));
|
||||
|
||||
Ref oldHead = db.getRef(Constants.HEAD);
|
||||
Ref oldHead = getOldHead();
|
||||
MergeResult result;
|
||||
try (Git git = new Git(db)) {
|
||||
MergeCommand mergeCmd = git.merge().setStrategy(mergeStrategy)
|
||||
|
@ -205,6 +205,14 @@ protected void run() throws Exception {
|
|||
}
|
||||
}
|
||||
|
||||
private Ref getOldHead() throws IOException {
|
||||
Ref oldHead = db.getRef(Constants.HEAD);
|
||||
if (oldHead == null) {
|
||||
throw die(CLIText.get().onBranchToBeBorn);
|
||||
}
|
||||
return oldHead;
|
||||
}
|
||||
|
||||
private boolean isMergedInto(Ref oldHead, AnyObjectId src)
|
||||
throws IOException {
|
||||
try (RevWalk revWalk = new RevWalk(db)) {
|
||||
|
|
|
@ -82,6 +82,9 @@ class Push extends TextBuiltin {
|
|||
@Option(name = "--all")
|
||||
private boolean all;
|
||||
|
||||
@Option(name = "--atomic")
|
||||
private boolean atomic;
|
||||
|
||||
@Option(name = "--tags")
|
||||
private boolean tags;
|
||||
|
||||
|
@ -122,6 +125,7 @@ protected void run() throws Exception {
|
|||
push.setPushTags();
|
||||
push.setRemote(remote);
|
||||
push.setThin(thin);
|
||||
push.setAtomic(atomic);
|
||||
push.setTimeout(timeout);
|
||||
Iterable<PushResult> results = push.call();
|
||||
for (PushResult result : results) {
|
||||
|
|
|
@ -0,0 +1,197 @@
|
|||
/*
|
||||
* Copyright (C) 2015, Kaloyan Raev <kaloyan.r@zend.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.pgm;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jgit.api.Git;
|
||||
import org.eclipse.jgit.api.RemoteAddCommand;
|
||||
import org.eclipse.jgit.api.RemoteListCommand;
|
||||
import org.eclipse.jgit.api.RemoteRemoveCommand;
|
||||
import org.eclipse.jgit.api.RemoteSetUrlCommand;
|
||||
import org.eclipse.jgit.api.errors.JGitInternalException;
|
||||
import org.eclipse.jgit.pgm.internal.CLIText;
|
||||
import org.eclipse.jgit.pgm.opt.CmdLineParser;
|
||||
import org.eclipse.jgit.transport.RemoteConfig;
|
||||
import org.eclipse.jgit.transport.URIish;
|
||||
import org.eclipse.jgit.util.io.ThrowingPrintWriter;
|
||||
import org.kohsuke.args4j.Argument;
|
||||
import org.kohsuke.args4j.Option;
|
||||
|
||||
@Command(common = false, usage = "usage_Remote")
|
||||
class Remote extends TextBuiltin {
|
||||
|
||||
@Option(name = "--verbose", aliases = { "-v" }, usage = "usage_beVerbose")
|
||||
private boolean verbose = false;
|
||||
|
||||
@Option(name = "--prune", aliases = {
|
||||
"-p" }, usage = "usage_pruneStaleTrackingRefs")
|
||||
private boolean prune;
|
||||
|
||||
@Option(name = "--push", usage = "usage_pushUrls")
|
||||
private boolean push;
|
||||
|
||||
@Argument(index = 0, metaVar = "metaVar_command")
|
||||
private String command;
|
||||
|
||||
@Argument(index = 1, metaVar = "metaVar_remoteName")
|
||||
private String name;
|
||||
|
||||
@Argument(index = 2, metaVar = "metaVar_uriish")
|
||||
private String uri;
|
||||
|
||||
@Override
|
||||
protected void run() throws Exception {
|
||||
try (Git git = new Git(db)) {
|
||||
if (command == null) {
|
||||
RemoteListCommand cmd = git.remoteList();
|
||||
List<RemoteConfig> remotes = cmd.call();
|
||||
print(remotes);
|
||||
} else if ("add".equals(command)) { //$NON-NLS-1$
|
||||
RemoteAddCommand cmd = git.remoteAdd();
|
||||
cmd.setName(name);
|
||||
cmd.setUri(new URIish(uri));
|
||||
cmd.call();
|
||||
} else if ("remove".equals(command) || "rm".equals(command)) { //$NON-NLS-1$ //$NON-NLS-2$
|
||||
RemoteRemoveCommand cmd = git.remoteRemove();
|
||||
cmd.setName(name);
|
||||
cmd.call();
|
||||
} else if ("set-url".equals(command)) { //$NON-NLS-1$
|
||||
RemoteSetUrlCommand cmd = git.remoteSetUrl();
|
||||
cmd.setName(name);
|
||||
cmd.setUri(new URIish(uri));
|
||||
cmd.setPush(push);
|
||||
cmd.call();
|
||||
} else if ("update".equals(command)) { //$NON-NLS-1$
|
||||
// reuse fetch command for basic implementation of remote update
|
||||
Fetch fetch = new Fetch();
|
||||
fetch.init(db, gitdir);
|
||||
|
||||
// redirect the output stream
|
||||
StringWriter osw = new StringWriter();
|
||||
fetch.outw = new ThrowingPrintWriter(osw);
|
||||
// redirect the error stream
|
||||
StringWriter esw = new StringWriter();
|
||||
fetch.errw = new ThrowingPrintWriter(esw);
|
||||
|
||||
List<String> fetchArgs = new ArrayList<>();
|
||||
if (verbose) {
|
||||
fetchArgs.add("--verbose"); //$NON-NLS-1$
|
||||
}
|
||||
if (prune) {
|
||||
fetchArgs.add("--prune"); //$NON-NLS-1$
|
||||
}
|
||||
if (name != null) {
|
||||
fetchArgs.add(name);
|
||||
}
|
||||
|
||||
fetch.execute(fetchArgs.toArray(new String[fetchArgs.size()]));
|
||||
|
||||
// flush the streams
|
||||
fetch.outw.flush();
|
||||
fetch.errw.flush();
|
||||
outw.println(osw.toString());
|
||||
errw.println(esw.toString());
|
||||
} else {
|
||||
throw new JGitInternalException(MessageFormat
|
||||
.format(CLIText.get().unknownSubcommand, command));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printUsageAndExit(final String message, final CmdLineParser clp)
|
||||
throws IOException {
|
||||
errw.println(message);
|
||||
errw.println("jgit remote [--verbose (-v)] [--help (-h)]"); //$NON-NLS-1$
|
||||
errw.println("jgit remote add name uri-ish [--help (-h)]"); //$NON-NLS-1$
|
||||
errw.println("jgit remote remove name [--help (-h)]"); //$NON-NLS-1$
|
||||
errw.println("jgit remote rm name [--help (-h)]"); //$NON-NLS-1$
|
||||
errw.println(
|
||||
"jgit remote [--verbose (-v)] update [name] [--prune (-p)] [--help (-h)]"); //$NON-NLS-1$
|
||||
errw.println("jgit remote set-url name uri-ish [--push] [--help (-h)]"); //$NON-NLS-1$
|
||||
|
||||
errw.println();
|
||||
clp.printUsage(errw, getResourceBundle());
|
||||
errw.println();
|
||||
|
||||
errw.flush();
|
||||
throw die(true);
|
||||
}
|
||||
|
||||
private void print(List<RemoteConfig> remotes) throws IOException {
|
||||
for (RemoteConfig remote : remotes) {
|
||||
String remoteName = remote.getName();
|
||||
if (verbose) {
|
||||
List<URIish> fetchURIs = remote.getURIs();
|
||||
List<URIish> pushURIs = remote.getPushURIs();
|
||||
|
||||
String fetchURI = ""; //$NON-NLS-1$
|
||||
if (!fetchURIs.isEmpty()) {
|
||||
fetchURI = fetchURIs.get(0).toString();
|
||||
} else if (!pushURIs.isEmpty()) {
|
||||
fetchURI = pushURIs.get(0).toString();
|
||||
}
|
||||
|
||||
String pushURI = ""; //$NON-NLS-1$
|
||||
if (!pushURIs.isEmpty()) {
|
||||
pushURI = pushURIs.get(0).toString();
|
||||
} else if (!fetchURIs.isEmpty()) {
|
||||
pushURI = fetchURIs.get(0).toString();
|
||||
}
|
||||
|
||||
outw.println(
|
||||
String.format("%s\t%s (fetch)", remoteName, fetchURI)); //$NON-NLS-1$
|
||||
outw.println(
|
||||
String.format("%s\t%s (push)", remoteName, pushURI)); //$NON-NLS-1$
|
||||
} else {
|
||||
outw.println(remoteName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright (C) 2009, Daniel Cheng (aka SDiZ) <git@sdiz.net>
|
||||
* Copyright (C) 2009, Daniel Cheng (aka SDiZ) <j16sdiz+freenet@gmail.com>
|
||||
* Copyright (C) 2015 Thomas Meyer <thomas@m3y3r.de>
|
||||
* and other copyright owners as documented in the project's IP log.
|
||||
*
|
||||
* This program and the accompanying materials are made available
|
||||
|
@ -51,14 +52,19 @@
|
|||
import java.util.Map;
|
||||
|
||||
import org.kohsuke.args4j.Argument;
|
||||
import org.kohsuke.args4j.CmdLineException;
|
||||
import org.kohsuke.args4j.Option;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.eclipse.jgit.lib.Ref;
|
||||
import org.eclipse.jgit.pgm.internal.CLIText;;
|
||||
|
||||
@Command(usage = "usage_RevParse")
|
||||
class RevParse extends TextBuiltin {
|
||||
@Option(name = "--all", usage = "usage_RevParseAll")
|
||||
boolean all = false;
|
||||
boolean all;
|
||||
|
||||
@Option(name = "--verify", usage = "usage_RevParseVerify")
|
||||
boolean verify;
|
||||
|
||||
@Argument(index = 0, metaVar = "metaVar_commitish")
|
||||
private final List<ObjectId> commits = new ArrayList<ObjectId>();
|
||||
|
@ -67,11 +73,17 @@ class RevParse extends TextBuiltin {
|
|||
protected void run() throws Exception {
|
||||
if (all) {
|
||||
Map<String, Ref> allRefs = db.getRefDatabase().getRefs(ALL);
|
||||
for (final Ref r : allRefs.values())
|
||||
for (final Ref r : allRefs.values()) {
|
||||
outw.println(r.getObjectId().name());
|
||||
}
|
||||
} else {
|
||||
for (final ObjectId o : commits)
|
||||
if (verify && commits.size() > 1) {
|
||||
throw new CmdLineException(CLIText.get().needSingleRevision);
|
||||
}
|
||||
|
||||
for (final ObjectId o : commits) {
|
||||
outw.println(o.name());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -242,9 +242,10 @@ public int compare(Test a, Test b) {
|
|||
}
|
||||
});
|
||||
|
||||
if (db.getDirectory() != null) {
|
||||
String name = db.getDirectory().getName();
|
||||
File parent = db.getDirectory().getParentFile();
|
||||
File directory = db.getDirectory();
|
||||
if (directory != null) {
|
||||
String name = directory.getName();
|
||||
File parent = directory.getParentFile();
|
||||
if (name.equals(Constants.DOT_GIT) && parent != null)
|
||||
name = parent.getName();
|
||||
outw.println(name + ": start at " + startId.name());
|
||||
|
|
|
@ -117,9 +117,12 @@ class RebuildCommitGraph extends TextBuiltin {
|
|||
@Override
|
||||
protected void run() throws Exception {
|
||||
if (!really && !db.getRefDatabase().getRefs(ALL).isEmpty()) {
|
||||
File directory = db.getDirectory();
|
||||
String absolutePath = directory == null ? "null" //$NON-NLS-1$
|
||||
: directory.getAbsolutePath();
|
||||
errw.println(
|
||||
MessageFormat.format(CLIText.get().fatalThisProgramWillDestroyTheRepository
|
||||
, db.getDirectory().getAbsolutePath(), REALLY));
|
||||
, absolutePath, REALLY));
|
||||
throw die(CLIText.get().needApprovalToDestroyCurrentRepository);
|
||||
}
|
||||
if (!refList.isFile())
|
||||
|
|
|
@ -341,9 +341,10 @@ private void run(Repository db) throws Exception {
|
|||
}
|
||||
}
|
||||
|
||||
if (db.getDirectory() != null) {
|
||||
String name = db.getDirectory().getName();
|
||||
File parent = db.getDirectory().getParentFile();
|
||||
File directory = db.getDirectory();
|
||||
if (directory != null) {
|
||||
String name = directory.getName();
|
||||
File parent = directory.getParentFile();
|
||||
if (name.equals(Constants.DOT_GIT) && parent != null)
|
||||
name = parent.getName();
|
||||
outw.println(name + ":"); //$NON-NLS-1$
|
||||
|
|
|
@ -187,6 +187,7 @@ public static String formatLine(String line) {
|
|||
/***/ public String metaVar_version;
|
||||
/***/ public String mostCommonlyUsedCommandsAre;
|
||||
/***/ public String needApprovalToDestroyCurrentRepository;
|
||||
/***/ public String needSingleRevision;
|
||||
/***/ public String noGitRepositoryConfigured;
|
||||
/***/ public String noNamesFound;
|
||||
/***/ public String noSuchFile;
|
||||
|
@ -201,6 +202,7 @@ public static String formatLine(String line) {
|
|||
/***/ public String notARevision;
|
||||
/***/ public String notATree;
|
||||
/***/ public String notAValidRefName;
|
||||
/***/ public String notAValidCommitName;
|
||||
/***/ public String notAnIndexFile;
|
||||
/***/ public String notAnObject;
|
||||
/***/ public String notFound;
|
||||
|
@ -245,6 +247,7 @@ public static String formatLine(String line) {
|
|||
/***/ public String treeIsRequired;
|
||||
/***/ public char[] unknownIoErrorStdout;
|
||||
/***/ public String unknownMergeStrategy;
|
||||
/***/ public String unknownSubcommand;
|
||||
/***/ public String unmergedPaths;
|
||||
/***/ public String unsupportedOperation;
|
||||
/***/ public String untrackedFiles;
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6" path="1" type="4"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry id="org.eclipse.jdt.launching.classpathentry.defaultClasspath"> <memento exportedEntriesOnly="false" project="org.eclipse.jgit.test"/> </runtimeClasspathEntry> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry path="3" projectName="org.eclipse.jgit.java7" type="1"/> "/>
|
||||
</listAttribute>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6" path="1" type="4"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry id="org.eclipse.jdt.launching.classpathentry.defaultClasspath"> <memento exportedEntriesOnly="false" project="org.eclipse.jgit.test"/> </runtimeClasspathEntry> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry path="3" projectName="org.eclipse.jgit.java7" type="1"/> "/>
|
||||
</listAttribute>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* Copyright (C) 2015, Kaloyan Raev <kaloyan.r@zend.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.api;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import org.eclipse.jgit.junit.RepositoryTestCase;
|
||||
import org.eclipse.jgit.lib.Constants;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.lib.StoredConfig;
|
||||
import org.eclipse.jgit.transport.RefSpec;
|
||||
import org.eclipse.jgit.transport.RemoteConfig;
|
||||
import org.eclipse.jgit.transport.URIish;
|
||||
|
||||
public class AbstractRemoteCommandTest extends RepositoryTestCase {
|
||||
|
||||
protected static final String REMOTE_NAME = "test";
|
||||
|
||||
protected RemoteConfig setupRemote()
|
||||
throws IOException, URISyntaxException {
|
||||
// create another repository
|
||||
Repository remoteRepository = createWorkRepository();
|
||||
|
||||
// set it up as a remote to this repository
|
||||
final StoredConfig config = db.getConfig();
|
||||
RemoteConfig remoteConfig = new RemoteConfig(config, REMOTE_NAME);
|
||||
|
||||
RefSpec refSpec = new RefSpec();
|
||||
refSpec = refSpec.setForceUpdate(true);
|
||||
refSpec = refSpec.setSourceDestination(Constants.R_HEADS + "*",
|
||||
Constants.R_REMOTES + REMOTE_NAME + "/*");
|
||||
remoteConfig.addFetchRefSpec(refSpec);
|
||||
|
||||
URIish uri = new URIish(
|
||||
remoteRepository.getDirectory().toURI().toURL());
|
||||
remoteConfig.addURI(uri);
|
||||
|
||||
remoteConfig.update(config);
|
||||
config.save();
|
||||
|
||||
return remoteConfig;
|
||||
}
|
||||
|
||||
protected void assertRemoteConfigEquals(RemoteConfig expected,
|
||||
RemoteConfig actual) {
|
||||
assertEquals(expected.getName(), actual.getName());
|
||||
assertEquals(expected.getURIs(), actual.getURIs());
|
||||
assertEquals(expected.getPushURIs(), actual.getPushURIs());
|
||||
assertEquals(expected.getFetchRefSpecs(), actual.getFetchRefSpecs());
|
||||
assertEquals(expected.getPushRefSpecs(), actual.getPushRefSpecs());
|
||||
}
|
||||
|
||||
}
|
|
@ -45,6 +45,7 @@
|
|||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -52,11 +53,13 @@
|
|||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
import org.eclipse.jgit.api.errors.FilterFailedException;
|
||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||
import org.eclipse.jgit.api.errors.NoFilepatternException;
|
||||
import org.eclipse.jgit.dircache.DirCache;
|
||||
import org.eclipse.jgit.dircache.DirCacheBuilder;
|
||||
import org.eclipse.jgit.dircache.DirCacheEntry;
|
||||
import org.eclipse.jgit.junit.JGitTestUtil;
|
||||
import org.eclipse.jgit.junit.RepositoryTestCase;
|
||||
import org.eclipse.jgit.lib.ConfigConstants;
|
||||
import org.eclipse.jgit.lib.Constants;
|
||||
|
@ -111,6 +114,191 @@ public void testAddExistingSingleFile() throws IOException, GitAPIException {
|
|||
indexState(CONTENT));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCleanFilter() throws IOException,
|
||||
GitAPIException {
|
||||
writeTrashFile(".gitattributes", "*.txt filter=tstFilter");
|
||||
writeTrashFile("src/a.tmp", "foo");
|
||||
// Caution: we need a trailing '\n' since sed on mac always appends
|
||||
// linefeeds if missing
|
||||
writeTrashFile("src/a.txt", "foo\n");
|
||||
File script = writeTempFile("sed s/o/e/g");
|
||||
|
||||
Git git = new Git(db);
|
||||
StoredConfig config = git.getRepository().getConfig();
|
||||
config.setString("filter", "tstFilter", "clean",
|
||||
"sh " + slashify(script.getPath()));
|
||||
config.save();
|
||||
|
||||
git.add().addFilepattern("src/a.txt").addFilepattern("src/a.tmp")
|
||||
.call();
|
||||
|
||||
assertEquals(
|
||||
"[src/a.tmp, mode:100644, content:foo][src/a.txt, mode:100644, content:fee\n]",
|
||||
indexState(CONTENT));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCleanFilterEnvironment()
|
||||
throws IOException, GitAPIException {
|
||||
writeTrashFile(".gitattributes", "*.txt filter=tstFilter");
|
||||
writeTrashFile("src/a.txt", "foo");
|
||||
File script = writeTempFile("echo $GIT_DIR; echo 1 >xyz");
|
||||
|
||||
Git git = new Git(db);
|
||||
StoredConfig config = git.getRepository().getConfig();
|
||||
config.setString("filter", "tstFilter", "clean",
|
||||
"sh " + slashify(script.getPath()));
|
||||
config.save();
|
||||
git.add().addFilepattern("src/a.txt").call();
|
||||
|
||||
String gitDir = db.getDirectory().getAbsolutePath();
|
||||
assertEquals("[src/a.txt, mode:100644, content:" + gitDir
|
||||
+ "\n]", indexState(CONTENT));
|
||||
assertTrue(new File(db.getWorkTree(), "xyz").exists());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleCleanFilter() throws IOException, GitAPIException {
|
||||
writeTrashFile(".gitattributes",
|
||||
"*.txt filter=tstFilter\n*.tmp filter=tstFilter2");
|
||||
// Caution: we need a trailing '\n' since sed on mac always appends
|
||||
// linefeeds if missing
|
||||
writeTrashFile("src/a.tmp", "foo\n");
|
||||
writeTrashFile("src/a.txt", "foo\n");
|
||||
File script = writeTempFile("sed s/o/e/g");
|
||||
File script2 = writeTempFile("sed s/f/x/g");
|
||||
|
||||
Git git = new Git(db);
|
||||
StoredConfig config = git.getRepository().getConfig();
|
||||
config.setString("filter", "tstFilter", "clean",
|
||||
"sh " + slashify(script.getPath()));
|
||||
config.setString("filter", "tstFilter2", "clean",
|
||||
"sh " + slashify(script2.getPath()));
|
||||
config.save();
|
||||
|
||||
git.add().addFilepattern("src/a.txt").addFilepattern("src/a.tmp")
|
||||
.call();
|
||||
|
||||
assertEquals(
|
||||
"[src/a.tmp, mode:100644, content:xoo\n][src/a.txt, mode:100644, content:fee\n]",
|
||||
indexState(CONTENT));
|
||||
|
||||
// TODO: multiple clean filters for one file???
|
||||
}
|
||||
|
||||
/**
|
||||
* The path of an added file name contains ';' and afterwards malicious
|
||||
* commands. Make sure when calling filter commands to properly escape the
|
||||
* filenames
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws GitAPIException
|
||||
*/
|
||||
@Test
|
||||
public void testCommandInjection() throws IOException, GitAPIException {
|
||||
// Caution: we need a trailing '\n' since sed on mac always appends
|
||||
// linefeeds if missing
|
||||
writeTrashFile("; echo virus", "foo\n");
|
||||
File script = writeTempFile("sed s/o/e/g");
|
||||
|
||||
Git git = new Git(db);
|
||||
StoredConfig config = git.getRepository().getConfig();
|
||||
config.setString("filter", "tstFilter", "clean",
|
||||
"sh " + slashify(script.getPath()) + " %f");
|
||||
writeTrashFile(".gitattributes", "* filter=tstFilter");
|
||||
|
||||
git.add().addFilepattern("; echo virus").call();
|
||||
// Without proper escaping the content would be "feovirus". The sed
|
||||
// command and the "echo virus" would contribute to the content
|
||||
assertEquals("[; echo virus, mode:100644, content:fee\n]",
|
||||
indexState(CONTENT));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBadCleanFilter() throws IOException, GitAPIException {
|
||||
writeTrashFile("a.txt", "foo");
|
||||
File script = writeTempFile("sedfoo s/o/e/g");
|
||||
|
||||
Git git = new Git(db);
|
||||
StoredConfig config = git.getRepository().getConfig();
|
||||
config.setString("filter", "tstFilter", "clean",
|
||||
"sh " + script.getPath());
|
||||
config.save();
|
||||
writeTrashFile(".gitattributes", "*.txt filter=tstFilter");
|
||||
|
||||
try {
|
||||
git.add().addFilepattern("a.txt").call();
|
||||
fail("Didn't received the expected exception");
|
||||
} catch (FilterFailedException e) {
|
||||
assertEquals(127, e.getReturnCode());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBadCleanFilter2() throws IOException, GitAPIException {
|
||||
writeTrashFile("a.txt", "foo");
|
||||
File script = writeTempFile("sed s/o/e/g");
|
||||
|
||||
Git git = new Git(db);
|
||||
StoredConfig config = git.getRepository().getConfig();
|
||||
config.setString("filter", "tstFilter", "clean",
|
||||
"shfoo " + script.getPath());
|
||||
config.save();
|
||||
writeTrashFile(".gitattributes", "*.txt filter=tstFilter");
|
||||
|
||||
try {
|
||||
git.add().addFilepattern("a.txt").call();
|
||||
fail("Didn't received the expected exception");
|
||||
} catch (FilterFailedException e) {
|
||||
assertEquals(127, e.getReturnCode());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCleanFilterReturning12() throws IOException,
|
||||
GitAPIException {
|
||||
writeTrashFile("a.txt", "foo");
|
||||
File script = writeTempFile("exit 12");
|
||||
|
||||
Git git = new Git(db);
|
||||
StoredConfig config = git.getRepository().getConfig();
|
||||
config.setString("filter", "tstFilter", "clean",
|
||||
"sh " + slashify(script.getPath()));
|
||||
config.save();
|
||||
writeTrashFile(".gitattributes", "*.txt filter=tstFilter");
|
||||
|
||||
try {
|
||||
git.add().addFilepattern("a.txt").call();
|
||||
fail("Didn't received the expected exception");
|
||||
} catch (FilterFailedException e) {
|
||||
assertEquals(12, e.getReturnCode());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotApplicableFilter() throws IOException, GitAPIException {
|
||||
writeTrashFile("a.txt", "foo");
|
||||
File script = writeTempFile("sed s/o/e/g");
|
||||
|
||||
Git git = new Git(db);
|
||||
StoredConfig config = git.getRepository().getConfig();
|
||||
config.setString("filter", "tstFilter", "something",
|
||||
"sh " + script.getPath());
|
||||
config.save();
|
||||
writeTrashFile(".gitattributes", "*.txt filter=tstFilter");
|
||||
|
||||
git.add().addFilepattern("a.txt").call();
|
||||
|
||||
assertEquals("[a.txt, mode:100644, content:foo]", indexState(CONTENT));
|
||||
}
|
||||
|
||||
private File writeTempFile(String body) throws IOException {
|
||||
File f = File.createTempFile("AddCommandTest_", "");
|
||||
JGitTestUtil.write(f, body);
|
||||
return f;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddExistingSingleSmallFileWithNewLine() throws IOException,
|
||||
GitAPIException {
|
||||
|
|
|
@ -43,6 +43,8 @@
|
|||
*/
|
||||
package org.eclipse.jgit.api;
|
||||
|
||||
import static org.eclipse.jgit.lib.Constants.MASTER;
|
||||
import static org.eclipse.jgit.lib.Constants.R_HEADS;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
@ -70,12 +72,14 @@
|
|||
import org.eclipse.jgit.api.errors.TransportException;
|
||||
import org.eclipse.jgit.dircache.DirCache;
|
||||
import org.eclipse.jgit.dircache.DirCacheEntry;
|
||||
import org.eclipse.jgit.junit.JGitTestUtil;
|
||||
import org.eclipse.jgit.junit.RepositoryTestCase;
|
||||
import org.eclipse.jgit.lib.ConfigConstants;
|
||||
import org.eclipse.jgit.lib.Constants;
|
||||
import org.eclipse.jgit.lib.Ref;
|
||||
import org.eclipse.jgit.lib.RefUpdate;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.lib.Sets;
|
||||
import org.eclipse.jgit.lib.StoredConfig;
|
||||
import org.eclipse.jgit.revwalk.RevCommit;
|
||||
import org.eclipse.jgit.storage.file.FileBasedConfig;
|
||||
|
@ -84,6 +88,7 @@
|
|||
import org.eclipse.jgit.transport.URIish;
|
||||
import org.eclipse.jgit.util.FileUtils;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
public class CheckoutCommandTest extends RepositoryTestCase {
|
||||
|
@ -134,7 +139,7 @@ public void testCheckout() throws Exception {
|
|||
@Test
|
||||
public void testCreateBranchOnCheckout() throws Exception {
|
||||
git.checkout().setCreateBranch(true).setName("test2").call();
|
||||
assertNotNull(db.getRef("test2"));
|
||||
assertNotNull(db.exactRef("refs/heads/test2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -237,8 +242,8 @@ public void testCheckoutRemoteTrackingWithUpstream() throws Exception {
|
|||
.setStartPoint("origin/test")
|
||||
.setUpstreamMode(SetupUpstreamMode.TRACK).call();
|
||||
|
||||
assertEquals("refs/heads/test", db2.getRef(Constants.HEAD).getTarget()
|
||||
.getName());
|
||||
assertEquals("refs/heads/test",
|
||||
db2.exactRef(Constants.HEAD).getTarget().getName());
|
||||
StoredConfig config = db2.getConfig();
|
||||
assertEquals("origin", config.getString(
|
||||
ConfigConstants.CONFIG_BRANCH_SECTION, "test",
|
||||
|
@ -345,7 +350,7 @@ public void testDetachedHeadOnCheckout() throws JGitInternalException,
|
|||
CheckoutCommand co = git.checkout();
|
||||
co.setName("master").call();
|
||||
|
||||
String commitId = db.getRef(Constants.MASTER).getObjectId().name();
|
||||
String commitId = db.exactRef(R_HEADS + MASTER).getObjectId().name();
|
||||
co = git.checkout();
|
||||
co.setName(commitId).call();
|
||||
|
||||
|
@ -443,7 +448,7 @@ private void assertNoHead() throws IOException {
|
|||
}
|
||||
|
||||
private void assertHeadDetached() throws IOException {
|
||||
Ref head = db.getRef(Constants.HEAD);
|
||||
Ref head = db.exactRef(Constants.HEAD);
|
||||
assertFalse(head.isSymbolic());
|
||||
assertSame(head, head.getTarget());
|
||||
}
|
||||
|
@ -554,4 +559,125 @@ public void testCheckoutAutoCrlfTrue() throws Exception {
|
|||
}
|
||||
org.junit.Assume.assumeTrue(foundUnsmudged);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSmudgeFilter_modifyExisting() throws IOException, GitAPIException {
|
||||
File script = writeTempFile("sed s/o/e/g");
|
||||
StoredConfig config = git.getRepository().getConfig();
|
||||
config.setString("filter", "tstFilter", "smudge",
|
||||
"sh " + slashify(script.getPath()));
|
||||
config.save();
|
||||
|
||||
writeTrashFile(".gitattributes", "*.txt filter=tstFilter");
|
||||
git.add().addFilepattern(".gitattributes").call();
|
||||
git.commit().setMessage("add filter").call();
|
||||
|
||||
writeTrashFile("src/a.tmp", "x");
|
||||
// Caution: we need a trailing '\n' since sed on mac always appends
|
||||
// linefeeds if missing
|
||||
writeTrashFile("src/a.txt", "x\n");
|
||||
git.add().addFilepattern("src/a.tmp").addFilepattern("src/a.txt")
|
||||
.call();
|
||||
RevCommit content1 = git.commit().setMessage("add content").call();
|
||||
|
||||
writeTrashFile("src/a.tmp", "foo");
|
||||
writeTrashFile("src/a.txt", "foo\n");
|
||||
git.add().addFilepattern("src/a.tmp").addFilepattern("src/a.txt")
|
||||
.call();
|
||||
RevCommit content2 = git.commit().setMessage("changed content").call();
|
||||
|
||||
git.checkout().setName(content1.getName()).call();
|
||||
git.checkout().setName(content2.getName()).call();
|
||||
|
||||
assertEquals(
|
||||
"[.gitattributes, mode:100644, content:*.txt filter=tstFilter][Test.txt, mode:100644, content:Some change][src/a.tmp, mode:100644, content:foo][src/a.txt, mode:100644, content:foo\n]",
|
||||
indexState(CONTENT));
|
||||
assertEquals(Sets.of("src/a.txt"), git.status().call().getModified());
|
||||
assertEquals("foo", read("src/a.tmp"));
|
||||
assertEquals("fee\n", read("src/a.txt"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSmudgeFilter_createNew()
|
||||
throws IOException, GitAPIException {
|
||||
File script = writeTempFile("sed s/o/e/g");
|
||||
StoredConfig config = git.getRepository().getConfig();
|
||||
config.setString("filter", "tstFilter", "smudge",
|
||||
"sh " + slashify(script.getPath()));
|
||||
config.save();
|
||||
|
||||
writeTrashFile("foo", "foo");
|
||||
git.add().addFilepattern("foo").call();
|
||||
RevCommit initial = git.commit().setMessage("initial").call();
|
||||
|
||||
writeTrashFile(".gitattributes", "*.txt filter=tstFilter");
|
||||
git.add().addFilepattern(".gitattributes").call();
|
||||
git.commit().setMessage("add filter").call();
|
||||
|
||||
writeTrashFile("src/a.tmp", "foo");
|
||||
// Caution: we need a trailing '\n' since sed on mac always appends
|
||||
// linefeeds if missing
|
||||
writeTrashFile("src/a.txt", "foo\n");
|
||||
git.add().addFilepattern("src/a.tmp").addFilepattern("src/a.txt")
|
||||
.call();
|
||||
RevCommit content = git.commit().setMessage("added content").call();
|
||||
|
||||
git.checkout().setName(initial.getName()).call();
|
||||
git.checkout().setName(content.getName()).call();
|
||||
|
||||
assertEquals(
|
||||
"[.gitattributes, mode:100644, content:*.txt filter=tstFilter][Test.txt, mode:100644, content:Some change][foo, mode:100644, content:foo][src/a.tmp, mode:100644, content:foo][src/a.txt, mode:100644, content:foo\n]",
|
||||
indexState(CONTENT));
|
||||
assertEquals("foo", read("src/a.tmp"));
|
||||
assertEquals("fee\n", read("src/a.txt"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testSmudgeAndClean() throws IOException, GitAPIException {
|
||||
// @TODO: fix this test
|
||||
File clean_filter = writeTempFile("sed s/V1/@version/g -");
|
||||
File smudge_filter = writeTempFile("sed s/@version/V1/g -");
|
||||
|
||||
Git git = new Git(db);
|
||||
StoredConfig config = git.getRepository().getConfig();
|
||||
config.setString("filter", "tstFilter", "smudge",
|
||||
"sh " + slashify(smudge_filter.getPath()));
|
||||
config.setString("filter", "tstFilter", "clean",
|
||||
"sh " + slashify(clean_filter.getPath()));
|
||||
config.save();
|
||||
writeTrashFile(".gitattributes", "*.txt filter=tstFilter");
|
||||
git.add().addFilepattern(".gitattributes").call();
|
||||
git.commit().setMessage("add attributes").call();
|
||||
|
||||
writeTrashFile("filterTest.txt", "hello world, V1");
|
||||
git.add().addFilepattern("filterTest.txt").call();
|
||||
git.commit().setMessage("add filterText.txt").call();
|
||||
assertEquals(
|
||||
"[.gitattributes, mode:100644, content:*.txt filter=tstFilter][Test.txt, mode:100644, content:Some other change][filterTest.txt, mode:100644, content:hello world, @version]",
|
||||
indexState(CONTENT));
|
||||
|
||||
git.checkout().setCreateBranch(true).setName("test2").call();
|
||||
writeTrashFile("filterTest.txt", "bon giorno world, V1");
|
||||
git.add().addFilepattern("filterTest.txt").call();
|
||||
git.commit().setMessage("modified filterText.txt").call();
|
||||
|
||||
assertTrue(git.status().call().isClean());
|
||||
assertEquals(
|
||||
"[.gitattributes, mode:100644, content:*.txt filter=tstFilter][Test.txt, mode:100644, content:Some other change][filterTest.txt, mode:100644, content:bon giorno world, @version]",
|
||||
indexState(CONTENT));
|
||||
|
||||
git.checkout().setName("refs/heads/test").call();
|
||||
assertTrue(git.status().call().isClean());
|
||||
assertEquals(
|
||||
"[.gitattributes, mode:100644, content:*.txt filter=tstFilter][Test.txt, mode:100644, content:Some other change][filterTest.txt, mode:100644, content:hello world, @version]",
|
||||
indexState(CONTENT));
|
||||
assertEquals("hello world, V1", read("filterTest.txt"));
|
||||
}
|
||||
|
||||
private File writeTempFile(String body) throws IOException {
|
||||
File f = File.createTempFile("AddCommandTest_", "");
|
||||
JGitTestUtil.write(f, body);
|
||||
return f;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -408,8 +408,10 @@ public void commitAfterSquashMerge() throws Exception {
|
|||
|
||||
checkoutBranch("refs/heads/master");
|
||||
|
||||
MergeResult result = git.merge().include(db.getRef("branch1"))
|
||||
.setSquash(true).call();
|
||||
MergeResult result = git.merge()
|
||||
.include(db.exactRef("refs/heads/branch1"))
|
||||
.setSquash(true)
|
||||
.call();
|
||||
|
||||
assertTrue(new File(db.getWorkTree(), "file1").exists());
|
||||
assertTrue(new File(db.getWorkTree(), "file2").exists());
|
||||
|
|
|
@ -43,6 +43,8 @@
|
|||
*/
|
||||
package org.eclipse.jgit.api;
|
||||
|
||||
import static org.eclipse.jgit.lib.Constants.MASTER;
|
||||
import static org.eclipse.jgit.lib.Constants.R_HEADS;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
@ -97,7 +99,7 @@ public void testMergeInItself() throws Exception {
|
|||
Git git = new Git(db);
|
||||
git.commit().setMessage("initial commit").call();
|
||||
|
||||
MergeResult result = git.merge().include(db.getRef(Constants.HEAD)).call();
|
||||
MergeResult result = git.merge().include(db.exactRef(Constants.HEAD)).call();
|
||||
assertEquals(MergeResult.MergeStatus.ALREADY_UP_TO_DATE, result.getMergeStatus());
|
||||
// no reflog entry written by merge
|
||||
assertEquals("commit (initial): initial commit",
|
||||
|
@ -115,7 +117,7 @@ public void testAlreadyUpToDate() throws Exception {
|
|||
createBranch(first, "refs/heads/branch1");
|
||||
|
||||
RevCommit second = git.commit().setMessage("second commit").call();
|
||||
MergeResult result = git.merge().include(db.getRef("refs/heads/branch1")).call();
|
||||
MergeResult result = git.merge().include(db.exactRef("refs/heads/branch1")).call();
|
||||
assertEquals(MergeResult.MergeStatus.ALREADY_UP_TO_DATE, result.getMergeStatus());
|
||||
assertEquals(second, result.getNewHead());
|
||||
// no reflog entry written by merge
|
||||
|
@ -135,7 +137,7 @@ public void testFastForward() throws Exception {
|
|||
|
||||
checkoutBranch("refs/heads/branch1");
|
||||
|
||||
MergeResult result = git.merge().include(db.getRef(Constants.MASTER)).call();
|
||||
MergeResult result = git.merge().include(db.exactRef(R_HEADS + MASTER)).call();
|
||||
|
||||
assertEquals(MergeResult.MergeStatus.FAST_FORWARD, result.getMergeStatus());
|
||||
assertEquals(second, result.getNewHead());
|
||||
|
@ -155,7 +157,7 @@ public void testFastForwardNoCommit() throws Exception {
|
|||
|
||||
checkoutBranch("refs/heads/branch1");
|
||||
|
||||
MergeResult result = git.merge().include(db.getRef(Constants.MASTER))
|
||||
MergeResult result = git.merge().include(db.exactRef(R_HEADS + MASTER))
|
||||
.setCommit(false).call();
|
||||
|
||||
assertEquals(MergeResult.MergeStatus.FAST_FORWARD,
|
||||
|
@ -186,7 +188,7 @@ public void testFastForwardWithFiles() throws Exception {
|
|||
checkoutBranch("refs/heads/branch1");
|
||||
assertFalse(new File(db.getWorkTree(), "file2").exists());
|
||||
|
||||
MergeResult result = git.merge().include(db.getRef(Constants.MASTER)).call();
|
||||
MergeResult result = git.merge().include(db.exactRef(R_HEADS + MASTER)).call();
|
||||
|
||||
assertTrue(new File(db.getWorkTree(), "file1").exists());
|
||||
assertTrue(new File(db.getWorkTree(), "file2").exists());
|
||||
|
@ -221,7 +223,7 @@ public void testMultipleHeads() throws Exception {
|
|||
|
||||
MergeCommand merge = git.merge();
|
||||
merge.include(second.getId());
|
||||
merge.include(db.getRef(Constants.MASTER));
|
||||
merge.include(db.exactRef(R_HEADS + MASTER));
|
||||
try {
|
||||
merge.call();
|
||||
fail("Expected exception not thrown when merging multiple heads");
|
||||
|
@ -248,7 +250,7 @@ public void testMergeSuccessAllStrategies(MergeStrategy mergeStrategy)
|
|||
git.commit().setMessage("third").call();
|
||||
|
||||
MergeResult result = git.merge().setStrategy(mergeStrategy)
|
||||
.include(db.getRef(Constants.MASTER)).call();
|
||||
.include(db.exactRef(R_HEADS + MASTER)).call();
|
||||
assertEquals(MergeStatus.MERGED, result.getMergeStatus());
|
||||
assertEquals(
|
||||
"merge refs/heads/master: Merge made by "
|
||||
|
@ -279,9 +281,9 @@ public void testMergeSuccessAllStrategiesNoCommit(
|
|||
|
||||
MergeResult result = git.merge().setStrategy(mergeStrategy)
|
||||
.setCommit(false)
|
||||
.include(db.getRef(Constants.MASTER)).call();
|
||||
.include(db.exactRef(R_HEADS + MASTER)).call();
|
||||
assertEquals(MergeStatus.MERGED_NOT_COMMITTED, result.getMergeStatus());
|
||||
assertEquals(db.getRef(Constants.HEAD).getTarget().getObjectId(),
|
||||
assertEquals(db.exactRef(Constants.HEAD).getTarget().getObjectId(),
|
||||
thirdCommit.getId());
|
||||
}
|
||||
|
||||
|
@ -378,7 +380,7 @@ public void testMergeMessage() throws Exception {
|
|||
git.add().addFilepattern("a").call();
|
||||
git.commit().setMessage("main").call();
|
||||
|
||||
Ref sideBranch = db.getRef("side");
|
||||
Ref sideBranch = db.exactRef("refs/heads/side");
|
||||
|
||||
git.merge().include(sideBranch)
|
||||
.setStrategy(MergeStrategy.RESOLVE).call();
|
||||
|
@ -590,7 +592,7 @@ public void testSuccessfulContentMergeNoCommit() throws Exception {
|
|||
.setCommit(false)
|
||||
.setStrategy(MergeStrategy.RESOLVE).call();
|
||||
assertEquals(MergeStatus.MERGED_NOT_COMMITTED, result.getMergeStatus());
|
||||
assertEquals(db.getRef(Constants.HEAD).getTarget().getObjectId(),
|
||||
assertEquals(db.exactRef(Constants.HEAD).getTarget().getObjectId(),
|
||||
thirdCommit.getId());
|
||||
|
||||
assertEquals("1(side)\na\n3(main)\n", read(new File(db.getWorkTree(),
|
||||
|
@ -1310,8 +1312,10 @@ public void testSquashFastForward() throws Exception {
|
|||
assertFalse(new File(db.getWorkTree(), "file2").exists());
|
||||
assertFalse(new File(db.getWorkTree(), "file3").exists());
|
||||
|
||||
MergeResult result = git.merge().include(db.getRef("branch1"))
|
||||
.setSquash(true).call();
|
||||
MergeResult result = git.merge()
|
||||
.include(db.exactRef("refs/heads/branch1"))
|
||||
.setSquash(true)
|
||||
.call();
|
||||
|
||||
assertTrue(new File(db.getWorkTree(), "file1").exists());
|
||||
assertTrue(new File(db.getWorkTree(), "file2").exists());
|
||||
|
@ -1375,8 +1379,10 @@ public void testSquashMerge() throws Exception {
|
|||
assertTrue(new File(db.getWorkTree(), "file2").exists());
|
||||
assertFalse(new File(db.getWorkTree(), "file3").exists());
|
||||
|
||||
MergeResult result = git.merge().include(db.getRef("branch1"))
|
||||
.setSquash(true).call();
|
||||
MergeResult result = git.merge()
|
||||
.include(db.exactRef("refs/heads/branch1"))
|
||||
.setSquash(true)
|
||||
.call();
|
||||
|
||||
assertTrue(new File(db.getWorkTree(), "file1").exists());
|
||||
assertTrue(new File(db.getWorkTree(), "file2").exists());
|
||||
|
@ -1430,8 +1436,10 @@ public void testSquashMergeConflict() throws Exception {
|
|||
assertTrue(new File(db.getWorkTree(), "file1").exists());
|
||||
assertTrue(new File(db.getWorkTree(), "file2").exists());
|
||||
|
||||
MergeResult result = git.merge().include(db.getRef("branch1"))
|
||||
.setSquash(true).call();
|
||||
MergeResult result = git.merge()
|
||||
.include(db.exactRef("refs/heads/branch1"))
|
||||
.setSquash(true)
|
||||
.call();
|
||||
|
||||
assertTrue(new File(db.getWorkTree(), "file1").exists());
|
||||
assertTrue(new File(db.getWorkTree(), "file2").exists());
|
||||
|
@ -1468,7 +1476,7 @@ public void testFastForwardOnly() throws Exception {
|
|||
|
||||
MergeCommand merge = git.merge();
|
||||
merge.setFastForward(FastForwardMode.FF_ONLY);
|
||||
merge.include(db.getRef(Constants.MASTER));
|
||||
merge.include(db.exactRef(R_HEADS + MASTER));
|
||||
MergeResult result = merge.call();
|
||||
|
||||
assertEquals(MergeStatus.FAST_FORWARD, result.getMergeStatus());
|
||||
|
@ -1485,7 +1493,7 @@ public void testNoFastForward() throws Exception {
|
|||
|
||||
MergeCommand merge = git.merge();
|
||||
merge.setFastForward(FastForwardMode.NO_FF);
|
||||
merge.include(db.getRef(Constants.MASTER));
|
||||
merge.include(db.exactRef(R_HEADS + MASTER));
|
||||
MergeResult result = merge.call();
|
||||
|
||||
assertEquals(MergeStatus.MERGED, result.getMergeStatus());
|
||||
|
@ -1505,7 +1513,7 @@ public void testNoFastForwardNoCommit() throws Exception {
|
|||
// when
|
||||
MergeCommand merge = git.merge();
|
||||
merge.setFastForward(FastForwardMode.NO_FF);
|
||||
merge.include(db.getRef(Constants.MASTER));
|
||||
merge.include(db.exactRef(R_HEADS + MASTER));
|
||||
merge.setCommit(false);
|
||||
MergeResult result = merge.call();
|
||||
|
||||
|
@ -1531,7 +1539,7 @@ public void testFastForwardOnlyNotPossible() throws Exception {
|
|||
git.commit().setMessage("second commit on branch1").call();
|
||||
MergeCommand merge = git.merge();
|
||||
merge.setFastForward(FastForwardMode.FF_ONLY);
|
||||
merge.include(db.getRef(Constants.MASTER));
|
||||
merge.include(db.exactRef(R_HEADS + MASTER));
|
||||
MergeResult result = merge.call();
|
||||
|
||||
assertEquals(MergeStatus.ABORTED, result.getMergeStatus());
|
||||
|
@ -1588,7 +1596,7 @@ public void testMergeWithMessageOption() throws Exception {
|
|||
git.add().addFilepattern("c").call();
|
||||
git.commit().setMessage("main").call();
|
||||
|
||||
Ref sideBranch = db.getRef("side");
|
||||
Ref sideBranch = db.exactRef("refs/heads/side");
|
||||
|
||||
git.merge().include(sideBranch).setStrategy(MergeStrategy.RESOLVE)
|
||||
.setMessage("user message").call();
|
||||
|
@ -1621,7 +1629,7 @@ public void testMergeConflictWithMessageOption() throws Exception {
|
|||
git.add().addFilepattern("a").call();
|
||||
git.commit().setMessage("main").call();
|
||||
|
||||
Ref sideBranch = db.getRef("side");
|
||||
Ref sideBranch = db.exactRef("refs/heads/side");
|
||||
|
||||
git.merge().include(sideBranch).setStrategy(MergeStrategy.RESOLVE)
|
||||
.setMessage("user message").call();
|
||||
|
|
|
@ -95,9 +95,9 @@ public void ref() throws Exception {
|
|||
tr.update("refs/heads/master", c);
|
||||
tr.update("refs/tags/tag", c);
|
||||
assertOneResult("master",
|
||||
git.nameRev().addRef(db.getRef("refs/heads/master")), c);
|
||||
git.nameRev().addRef(db.exactRef("refs/heads/master")), c);
|
||||
assertOneResult("tag",
|
||||
git.nameRev().addRef(db.getRef("refs/tags/tag")), c);
|
||||
git.nameRev().addRef(db.exactRef("refs/tags/tag")), c);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -138,11 +138,9 @@ public void testPrePushHook() throws JGitInternalException, IOException,
|
|||
|
||||
RefSpec spec = new RefSpec("refs/heads/master:refs/heads/x");
|
||||
git1.push().setRemote("test").setRefSpecs(spec).call();
|
||||
assertEquals(
|
||||
"1:test, 2:file://" + db2.getDirectory().toPath() //
|
||||
+ "/, 3:\n" + "refs/heads/master " + commit.getName()
|
||||
+ " refs/heads/x " + ObjectId.zeroId().name(),
|
||||
read(hookOutput));
|
||||
assertEquals("1:test, 2:" + uri + ", 3:\n" + "refs/heads/master "
|
||||
+ commit.getName() + " refs/heads/x "
|
||||
+ ObjectId.zeroId().name(), read(hookOutput));
|
||||
}
|
||||
|
||||
private File writeHookFile(final String name, final String data)
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright (C) 2015, Kaloyan Raev <kaloyan.r@zend.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.api;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.transport.RemoteConfig;
|
||||
import org.eclipse.jgit.transport.URIish;
|
||||
import org.junit.Test;
|
||||
|
||||
public class RemoteAddCommandTest extends AbstractRemoteCommandTest {
|
||||
|
||||
@Test
|
||||
public void testAdd() throws Exception {
|
||||
// create another repository
|
||||
Repository remoteRepository = createWorkRepository();
|
||||
URIish uri = new URIish(
|
||||
remoteRepository.getDirectory().toURI().toURL());
|
||||
|
||||
// execute the command to add a new remote
|
||||
RemoteAddCommand cmd = Git.wrap(db).remoteAdd();
|
||||
cmd.setName(REMOTE_NAME);
|
||||
cmd.setUri(uri);
|
||||
RemoteConfig remote = cmd.call();
|
||||
|
||||
// assert that the added remote represents the remote repository
|
||||
assertEquals(REMOTE_NAME, remote.getName());
|
||||
assertArrayEquals(new URIish[] { uri }, remote.getURIs().toArray());
|
||||
assertEquals(1, remote.getFetchRefSpecs().size());
|
||||
assertEquals(
|
||||
String.format("+refs/heads/*:refs/remotes/%s/*", REMOTE_NAME),
|
||||
remote.getFetchRefSpecs().get(0).toString());
|
||||
|
||||
// assert that the added remote is available in the git configuration
|
||||
assertRemoteConfigEquals(remote,
|
||||
new RemoteConfig(db.getConfig(), REMOTE_NAME));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (C) 2015, Kaloyan Raev <kaloyan.r@zend.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.api;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.eclipse.jgit.transport.RemoteConfig;
|
||||
import org.junit.Test;
|
||||
|
||||
public class RemoteDeleteCommandTest extends AbstractRemoteCommandTest {
|
||||
|
||||
@Test
|
||||
public void testDelete() throws Exception {
|
||||
// setup an initial remote
|
||||
RemoteConfig remoteConfig = setupRemote();
|
||||
|
||||
// execute the command to remove the remote
|
||||
RemoteRemoveCommand cmd = Git.wrap(db).remoteRemove();
|
||||
cmd.setName(REMOTE_NAME);
|
||||
RemoteConfig remote = cmd.call();
|
||||
|
||||
// assert that the removed remote is the initial remote
|
||||
assertRemoteConfigEquals(remoteConfig, remote);
|
||||
// assert that there are no remotes left
|
||||
assertTrue(RemoteConfig.getAllRemoteConfigs(db.getConfig()).isEmpty());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (C) 2015, Kaloyan Raev <kaloyan.r@zend.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.api;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jgit.transport.RemoteConfig;
|
||||
import org.junit.Test;
|
||||
|
||||
public class RemoteListCommandTest extends AbstractRemoteCommandTest {
|
||||
|
||||
@Test
|
||||
public void testList() throws Exception {
|
||||
// setup an initial remote
|
||||
RemoteConfig remoteConfig = setupRemote();
|
||||
|
||||
// execute the command to list the remotes
|
||||
List<RemoteConfig> remotes = Git.wrap(db).remoteList().call();
|
||||
|
||||
// assert that there is only one remote
|
||||
assertEquals(1, remotes.size());
|
||||
// assert that the available remote is the initial remote
|
||||
assertRemoteConfigEquals(remoteConfig, remotes.get(0));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Copyright (C) 2015, Kaloyan Raev <kaloyan.r@zend.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.api;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.eclipse.jgit.transport.RemoteConfig;
|
||||
import org.eclipse.jgit.transport.URIish;
|
||||
import org.junit.Test;
|
||||
|
||||
public class RemoteSetUrlCommandTest extends AbstractRemoteCommandTest {
|
||||
|
||||
@Test
|
||||
public void testSetUrl() throws Exception {
|
||||
// setup an initial remote
|
||||
setupRemote();
|
||||
|
||||
// execute the command to change the fetch url
|
||||
RemoteSetUrlCommand cmd = Git.wrap(db).remoteSetUrl();
|
||||
cmd.setName(REMOTE_NAME);
|
||||
URIish newUri = new URIish("git://test.com/test");
|
||||
cmd.setUri(newUri);
|
||||
RemoteConfig remote = cmd.call();
|
||||
|
||||
// assert that the changed remote has the new fetch url
|
||||
assertEquals(REMOTE_NAME, remote.getName());
|
||||
assertArrayEquals(new URIish[] { newUri }, remote.getURIs().toArray());
|
||||
|
||||
// assert that the changed remote is available in the git configuration
|
||||
assertRemoteConfigEquals(remote,
|
||||
new RemoteConfig(db.getConfig(), REMOTE_NAME));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetPushUrl() throws Exception {
|
||||
// setup an initial remote
|
||||
RemoteConfig remoteConfig = setupRemote();
|
||||
|
||||
// execute the command to change the push url
|
||||
RemoteSetUrlCommand cmd = Git.wrap(db).remoteSetUrl();
|
||||
cmd.setName(REMOTE_NAME);
|
||||
URIish newUri = new URIish("git://test.com/test");
|
||||
cmd.setUri(newUri);
|
||||
cmd.setPush(true);
|
||||
RemoteConfig remote = cmd.call();
|
||||
|
||||
// assert that the changed remote has the old fetch url and the new push
|
||||
// url
|
||||
assertEquals(REMOTE_NAME, remote.getName());
|
||||
assertEquals(remoteConfig.getURIs(), remote.getURIs());
|
||||
assertArrayEquals(new URIish[] { newUri },
|
||||
remote.getPushURIs().toArray());
|
||||
|
||||
// assert that the changed remote is available in the git configuration
|
||||
assertRemoteConfigEquals(remote,
|
||||
new RemoteConfig(db.getConfig(), REMOTE_NAME));
|
||||
}
|
||||
|
||||
}
|
|
@ -477,8 +477,10 @@ public void testHardResetAfterSquashMerge() throws Exception {
|
|||
|
||||
checkoutBranch("refs/heads/master");
|
||||
|
||||
MergeResult result = g.merge().include(db.getRef("branch1"))
|
||||
.setSquash(true).call();
|
||||
MergeResult result = g.merge()
|
||||
.include(db.exactRef("refs/heads/branch1"))
|
||||
.setSquash(true)
|
||||
.call();
|
||||
|
||||
assertEquals(MergeResult.MergeStatus.FAST_FORWARD_SQUASHED,
|
||||
result.getMergeStatus());
|
||||
|
|
|
@ -110,7 +110,7 @@ private void validateStashedCommit(final RevCommit commit,
|
|||
int parentCount)
|
||||
throws IOException {
|
||||
assertNotNull(commit);
|
||||
Ref stashRef = db.getRef(Constants.R_STASH);
|
||||
Ref stashRef = db.exactRef(Constants.R_STASH);
|
||||
assertNotNull(stashRef);
|
||||
assertEquals(commit, stashRef.getObjectId());
|
||||
assertNotNull(commit.getAuthorIdent());
|
||||
|
|
|
@ -96,13 +96,13 @@ public void dropWithNoStashedCommits() throws Exception {
|
|||
@Test
|
||||
public void dropWithInvalidLogIndex() throws Exception {
|
||||
write(committedFile, "content2");
|
||||
Ref stashRef = git.getRepository().getRef(Constants.R_STASH);
|
||||
Ref stashRef = git.getRepository().exactRef(Constants.R_STASH);
|
||||
assertNull(stashRef);
|
||||
RevCommit stashed = git.stashCreate().call();
|
||||
assertNotNull(stashed);
|
||||
stashRef = git.getRepository().getRef(Constants.R_STASH);
|
||||
assertEquals(stashed, git.getRepository().getRef(Constants.R_STASH)
|
||||
.getObjectId());
|
||||
stashRef = git.getRepository().exactRef(Constants.R_STASH);
|
||||
assertEquals(stashed,
|
||||
git.getRepository().exactRef(Constants.R_STASH).getObjectId());
|
||||
try {
|
||||
assertNull(git.stashDrop().setStashRef(100).call());
|
||||
fail("Exception not thrown");
|
||||
|
@ -115,15 +115,15 @@ public void dropWithInvalidLogIndex() throws Exception {
|
|||
@Test
|
||||
public void dropSingleStashedCommit() throws Exception {
|
||||
write(committedFile, "content2");
|
||||
Ref stashRef = git.getRepository().getRef(Constants.R_STASH);
|
||||
Ref stashRef = git.getRepository().exactRef(Constants.R_STASH);
|
||||
assertNull(stashRef);
|
||||
RevCommit stashed = git.stashCreate().call();
|
||||
assertNotNull(stashed);
|
||||
stashRef = git.getRepository().getRef(Constants.R_STASH);
|
||||
assertEquals(stashed, git.getRepository().getRef(Constants.R_STASH)
|
||||
.getObjectId());
|
||||
stashRef = git.getRepository().exactRef(Constants.R_STASH);
|
||||
assertEquals(stashed,
|
||||
git.getRepository().exactRef(Constants.R_STASH).getObjectId());
|
||||
assertNull(git.stashDrop().call());
|
||||
stashRef = git.getRepository().getRef(Constants.R_STASH);
|
||||
stashRef = git.getRepository().exactRef(Constants.R_STASH);
|
||||
assertNull(stashRef);
|
||||
|
||||
ReflogReader reader = git.getRepository().getReflogReader(
|
||||
|
@ -134,25 +134,25 @@ public void dropSingleStashedCommit() throws Exception {
|
|||
@Test
|
||||
public void dropAll() throws Exception {
|
||||
write(committedFile, "content2");
|
||||
Ref stashRef = git.getRepository().getRef(Constants.R_STASH);
|
||||
Ref stashRef = git.getRepository().exactRef(Constants.R_STASH);
|
||||
assertNull(stashRef);
|
||||
RevCommit firstStash = git.stashCreate().call();
|
||||
assertNotNull(firstStash);
|
||||
stashRef = git.getRepository().getRef(Constants.R_STASH);
|
||||
stashRef = git.getRepository().exactRef(Constants.R_STASH);
|
||||
assertNotNull(stashRef);
|
||||
assertEquals(firstStash, git.getRepository().getRef(Constants.R_STASH)
|
||||
.getObjectId());
|
||||
assertEquals(firstStash,
|
||||
git.getRepository().exactRef(Constants.R_STASH).getObjectId());
|
||||
|
||||
write(committedFile, "content3");
|
||||
RevCommit secondStash = git.stashCreate().call();
|
||||
assertNotNull(secondStash);
|
||||
stashRef = git.getRepository().getRef(Constants.R_STASH);
|
||||
stashRef = git.getRepository().exactRef(Constants.R_STASH);
|
||||
assertNotNull(stashRef);
|
||||
assertEquals(secondStash, git.getRepository().getRef(Constants.R_STASH)
|
||||
.getObjectId());
|
||||
assertEquals(secondStash,
|
||||
git.getRepository().exactRef(Constants.R_STASH).getObjectId());
|
||||
|
||||
assertNull(git.stashDrop().setAll(true).call());
|
||||
assertNull(git.getRepository().getRef(Constants.R_STASH));
|
||||
assertNull(git.getRepository().exactRef(Constants.R_STASH));
|
||||
|
||||
ReflogReader reader = git.getRepository().getReflogReader(
|
||||
Constants.R_STASH);
|
||||
|
@ -162,25 +162,25 @@ public void dropAll() throws Exception {
|
|||
@Test
|
||||
public void dropFirstStashedCommit() throws Exception {
|
||||
write(committedFile, "content2");
|
||||
Ref stashRef = git.getRepository().getRef(Constants.R_STASH);
|
||||
Ref stashRef = git.getRepository().exactRef(Constants.R_STASH);
|
||||
assertNull(stashRef);
|
||||
RevCommit firstStash = git.stashCreate().call();
|
||||
assertNotNull(firstStash);
|
||||
stashRef = git.getRepository().getRef(Constants.R_STASH);
|
||||
stashRef = git.getRepository().exactRef(Constants.R_STASH);
|
||||
assertNotNull(stashRef);
|
||||
assertEquals(firstStash, git.getRepository().getRef(Constants.R_STASH)
|
||||
.getObjectId());
|
||||
assertEquals(firstStash,
|
||||
git.getRepository().exactRef(Constants.R_STASH).getObjectId());
|
||||
|
||||
write(committedFile, "content3");
|
||||
RevCommit secondStash = git.stashCreate().call();
|
||||
assertNotNull(secondStash);
|
||||
stashRef = git.getRepository().getRef(Constants.R_STASH);
|
||||
stashRef = git.getRepository().exactRef(Constants.R_STASH);
|
||||
assertNotNull(stashRef);
|
||||
assertEquals(secondStash, git.getRepository().getRef(Constants.R_STASH)
|
||||
.getObjectId());
|
||||
assertEquals(secondStash,
|
||||
git.getRepository().exactRef(Constants.R_STASH).getObjectId());
|
||||
|
||||
assertEquals(firstStash, git.stashDrop().call());
|
||||
stashRef = git.getRepository().getRef(Constants.R_STASH);
|
||||
stashRef = git.getRepository().exactRef(Constants.R_STASH);
|
||||
assertNotNull(stashRef);
|
||||
assertEquals(firstStash, stashRef.getObjectId());
|
||||
|
||||
|
@ -196,33 +196,33 @@ public void dropFirstStashedCommit() throws Exception {
|
|||
@Test
|
||||
public void dropMiddleStashCommit() throws Exception {
|
||||
write(committedFile, "content2");
|
||||
Ref stashRef = git.getRepository().getRef(Constants.R_STASH);
|
||||
Ref stashRef = git.getRepository().exactRef(Constants.R_STASH);
|
||||
assertNull(stashRef);
|
||||
RevCommit firstStash = git.stashCreate().call();
|
||||
assertNotNull(firstStash);
|
||||
stashRef = git.getRepository().getRef(Constants.R_STASH);
|
||||
stashRef = git.getRepository().exactRef(Constants.R_STASH);
|
||||
assertNotNull(stashRef);
|
||||
assertEquals(firstStash, git.getRepository().getRef(Constants.R_STASH)
|
||||
.getObjectId());
|
||||
assertEquals(firstStash,
|
||||
git.getRepository().exactRef(Constants.R_STASH).getObjectId());
|
||||
|
||||
write(committedFile, "content3");
|
||||
RevCommit secondStash = git.stashCreate().call();
|
||||
assertNotNull(secondStash);
|
||||
stashRef = git.getRepository().getRef(Constants.R_STASH);
|
||||
stashRef = git.getRepository().exactRef(Constants.R_STASH);
|
||||
assertNotNull(stashRef);
|
||||
assertEquals(secondStash, git.getRepository().getRef(Constants.R_STASH)
|
||||
.getObjectId());
|
||||
assertEquals(secondStash,
|
||||
git.getRepository().exactRef(Constants.R_STASH).getObjectId());
|
||||
|
||||
write(committedFile, "content4");
|
||||
RevCommit thirdStash = git.stashCreate().call();
|
||||
assertNotNull(thirdStash);
|
||||
stashRef = git.getRepository().getRef(Constants.R_STASH);
|
||||
stashRef = git.getRepository().exactRef(Constants.R_STASH);
|
||||
assertNotNull(stashRef);
|
||||
assertEquals(thirdStash, git.getRepository().getRef(Constants.R_STASH)
|
||||
.getObjectId());
|
||||
assertEquals(thirdStash,
|
||||
git.getRepository().exactRef(Constants.R_STASH).getObjectId());
|
||||
|
||||
assertEquals(thirdStash, git.stashDrop().setStashRef(1).call());
|
||||
stashRef = git.getRepository().getRef(Constants.R_STASH);
|
||||
stashRef = git.getRepository().exactRef(Constants.R_STASH);
|
||||
assertNotNull(stashRef);
|
||||
assertEquals(thirdStash, stashRef.getObjectId());
|
||||
|
||||
|
@ -241,46 +241,46 @@ public void dropMiddleStashCommit() throws Exception {
|
|||
@Test
|
||||
public void dropBoundaryStashedCommits() throws Exception {
|
||||
write(committedFile, "content2");
|
||||
Ref stashRef = git.getRepository().getRef(Constants.R_STASH);
|
||||
Ref stashRef = git.getRepository().exactRef(Constants.R_STASH);
|
||||
assertNull(stashRef);
|
||||
RevCommit firstStash = git.stashCreate().call();
|
||||
assertNotNull(firstStash);
|
||||
stashRef = git.getRepository().getRef(Constants.R_STASH);
|
||||
stashRef = git.getRepository().exactRef(Constants.R_STASH);
|
||||
assertNotNull(stashRef);
|
||||
assertEquals(firstStash, git.getRepository().getRef(Constants.R_STASH)
|
||||
.getObjectId());
|
||||
assertEquals(firstStash,
|
||||
git.getRepository().exactRef(Constants.R_STASH).getObjectId());
|
||||
|
||||
write(committedFile, "content3");
|
||||
RevCommit secondStash = git.stashCreate().call();
|
||||
assertNotNull(secondStash);
|
||||
stashRef = git.getRepository().getRef(Constants.R_STASH);
|
||||
stashRef = git.getRepository().exactRef(Constants.R_STASH);
|
||||
assertNotNull(stashRef);
|
||||
assertEquals(secondStash, git.getRepository().getRef(Constants.R_STASH)
|
||||
.getObjectId());
|
||||
assertEquals(secondStash,
|
||||
git.getRepository().exactRef(Constants.R_STASH).getObjectId());
|
||||
|
||||
write(committedFile, "content4");
|
||||
RevCommit thirdStash = git.stashCreate().call();
|
||||
assertNotNull(thirdStash);
|
||||
stashRef = git.getRepository().getRef(Constants.R_STASH);
|
||||
stashRef = git.getRepository().exactRef(Constants.R_STASH);
|
||||
assertNotNull(stashRef);
|
||||
assertEquals(thirdStash, git.getRepository().getRef(Constants.R_STASH)
|
||||
.getObjectId());
|
||||
assertEquals(thirdStash,
|
||||
git.getRepository().exactRef(Constants.R_STASH).getObjectId());
|
||||
|
||||
write(committedFile, "content5");
|
||||
RevCommit fourthStash = git.stashCreate().call();
|
||||
assertNotNull(fourthStash);
|
||||
stashRef = git.getRepository().getRef(Constants.R_STASH);
|
||||
stashRef = git.getRepository().exactRef(Constants.R_STASH);
|
||||
assertNotNull(stashRef);
|
||||
assertEquals(fourthStash, git.getRepository().getRef(Constants.R_STASH)
|
||||
.getObjectId());
|
||||
assertEquals(fourthStash,
|
||||
git.getRepository().exactRef(Constants.R_STASH).getObjectId());
|
||||
|
||||
assertEquals(thirdStash, git.stashDrop().call());
|
||||
stashRef = git.getRepository().getRef(Constants.R_STASH);
|
||||
stashRef = git.getRepository().exactRef(Constants.R_STASH);
|
||||
assertNotNull(stashRef);
|
||||
assertEquals(thirdStash, stashRef.getObjectId());
|
||||
|
||||
assertEquals(thirdStash, git.stashDrop().setStashRef(2).call());
|
||||
stashRef = git.getRepository().getRef(Constants.R_STASH);
|
||||
stashRef = git.getRepository().exactRef(Constants.R_STASH);
|
||||
assertNotNull(stashRef);
|
||||
assertEquals(thirdStash, stashRef.getObjectId());
|
||||
|
||||
|
|
|
@ -52,9 +52,7 @@
|
|||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jgit.api.Git;
|
||||
import org.eclipse.jgit.attributes.Attribute.State;
|
||||
|
@ -243,27 +241,29 @@ private void assertIteration(FileMode type, String pathName,
|
|||
DirCacheIterator itr = walk.getTree(0, DirCacheIterator.class);
|
||||
assertNotNull("has tree", itr);
|
||||
|
||||
AttributesNode attributeNode = itr.getEntryAttributesNode(db
|
||||
AttributesNode attributesNode = itr.getEntryAttributesNode(db
|
||||
.newObjectReader());
|
||||
assertAttributeNode(pathName, attributeNode, nodeAttrs);
|
||||
assertAttributesNode(pathName, attributesNode, nodeAttrs);
|
||||
|
||||
if (D.equals(type))
|
||||
walk.enterSubtree();
|
||||
|
||||
}
|
||||
|
||||
private void assertAttributeNode(String pathName,
|
||||
AttributesNode attributeNode, List<Attribute> nodeAttrs) {
|
||||
if (attributeNode == null)
|
||||
private void assertAttributesNode(String pathName,
|
||||
AttributesNode attributesNode, List<Attribute> nodeAttrs) {
|
||||
if (attributesNode == null)
|
||||
assertTrue(nodeAttrs == null || nodeAttrs.isEmpty());
|
||||
else {
|
||||
|
||||
Map<String, Attribute> entryAttributes = new LinkedHashMap<String, Attribute>();
|
||||
attributeNode.getAttributes(pathName, false, entryAttributes);
|
||||
Attributes entryAttributes = new Attributes();
|
||||
attributesNode.getAttributes(pathName,
|
||||
false, entryAttributes);
|
||||
|
||||
if (nodeAttrs != null && !nodeAttrs.isEmpty()) {
|
||||
for (Attribute attribute : nodeAttrs) {
|
||||
assertThat(entryAttributes.values(), hasItem(attribute));
|
||||
assertThat(entryAttributes.getAll(),
|
||||
hasItem(attribute));
|
||||
}
|
||||
} else {
|
||||
assertTrue(
|
||||
|
|
|
@ -49,10 +49,6 @@
|
|||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
|
@ -60,7 +56,7 @@
|
|||
/**
|
||||
* Test {@link AttributesNode}
|
||||
*/
|
||||
public class AttributeNodeTest {
|
||||
public class AttributesNodeTest {
|
||||
|
||||
private static final Attribute A_SET_ATTR = new Attribute("A", SET);
|
||||
|
||||
|
@ -104,8 +100,8 @@ public void testNegativePattern() throws IOException {
|
|||
is = new ByteArrayInputStream(attributeFileContent.getBytes());
|
||||
AttributesNode node = new AttributesNode();
|
||||
node.parse(is);
|
||||
assertAttribute("file.type1", node, Collections.<Attribute> emptySet());
|
||||
assertAttribute("file.type2", node, Collections.<Attribute> emptySet());
|
||||
assertAttribute("file.type1", node, new Attributes());
|
||||
assertAttribute("file.type2", node, new Attributes());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -115,7 +111,7 @@ public void testEmptyNegativeAttributeKey() throws IOException {
|
|||
is = new ByteArrayInputStream(attributeFileContent.getBytes());
|
||||
AttributesNode node = new AttributesNode();
|
||||
node.parse(is);
|
||||
assertAttribute("file.type1", node, Collections.<Attribute> emptySet());
|
||||
assertAttribute("file.type1", node, new Attributes());
|
||||
assertAttribute("file.type2", node, asSet(A_UNSET_ATTR));
|
||||
}
|
||||
|
||||
|
@ -127,8 +123,8 @@ public void testEmptyValueKey() throws IOException {
|
|||
is = new ByteArrayInputStream(attributeFileContent.getBytes());
|
||||
AttributesNode node = new AttributesNode();
|
||||
node.parse(is);
|
||||
assertAttribute("file.type1", node, Collections.<Attribute> emptySet());
|
||||
assertAttribute("file.type2", node, Collections.<Attribute> emptySet());
|
||||
assertAttribute("file.type1", node, new Attributes());
|
||||
assertAttribute("file.type2", node, new Attributes());
|
||||
assertAttribute("file.type3", node, asSet(new Attribute("attr", "")));
|
||||
}
|
||||
|
||||
|
@ -166,17 +162,14 @@ public void testTabSeparator() throws IOException {
|
|||
}
|
||||
|
||||
private void assertAttribute(String path, AttributesNode node,
|
||||
Set<Attribute> attrs) {
|
||||
HashMap<String, Attribute> attributes = new HashMap<String, Attribute>();
|
||||
Attributes attrs) {
|
||||
Attributes attributes = new Attributes();
|
||||
node.getAttributes(path, false, attributes);
|
||||
assertEquals(attrs, new HashSet<Attribute>(attributes.values()));
|
||||
assertEquals(attrs, attributes);
|
||||
}
|
||||
|
||||
static Set<Attribute> asSet(Attribute... attrs) {
|
||||
Set<Attribute> result = new HashSet<Attribute>();
|
||||
for (Attribute attr : attrs)
|
||||
result.add(attr);
|
||||
return result;
|
||||
static Attributes asSet(Attribute... attrs) {
|
||||
return new Attributes(attrs);
|
||||
}
|
||||
|
||||
}
|
|
@ -53,9 +53,7 @@
|
|||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jgit.attributes.Attribute.State;
|
||||
import org.eclipse.jgit.errors.CorruptObjectException;
|
||||
|
@ -76,14 +74,10 @@ public class AttributesNodeWorkingTreeIteratorTest extends RepositoryTestCase {
|
|||
|
||||
private static final FileMode F = FileMode.REGULAR_FILE;
|
||||
|
||||
private static Attribute EOL_CRLF = new Attribute("eol", "crlf");
|
||||
|
||||
private static Attribute EOL_LF = new Attribute("eol", "lf");
|
||||
|
||||
private static Attribute DELTA_UNSET = new Attribute("delta", State.UNSET);
|
||||
|
||||
private static Attribute CUSTOM_VALUE = new Attribute("custom", "value");
|
||||
|
||||
private TreeWalk walk;
|
||||
|
||||
@Test
|
||||
|
@ -112,25 +106,19 @@ public void testRules() throws Exception {
|
|||
walk = beginWalk();
|
||||
|
||||
assertIteration(F, ".gitattributes");
|
||||
assertIteration(F, "global.txt", asList(EOL_LF), null,
|
||||
asList(CUSTOM_VALUE));
|
||||
assertIteration(F, "readme.txt", asList(EOL_LF), null,
|
||||
asList(CUSTOM_VALUE));
|
||||
assertIteration(F, "global.txt", asList(EOL_LF));
|
||||
assertIteration(F, "readme.txt", asList(EOL_LF));
|
||||
|
||||
assertIteration(D, "src");
|
||||
|
||||
assertIteration(D, "src/config");
|
||||
assertIteration(F, "src/config/.gitattributes");
|
||||
assertIteration(F, "src/config/readme.txt", asList(DELTA_UNSET), null,
|
||||
asList(CUSTOM_VALUE));
|
||||
assertIteration(F, "src/config/windows.file", null, asList(EOL_CRLF),
|
||||
null);
|
||||
assertIteration(F, "src/config/windows.txt", asList(DELTA_UNSET),
|
||||
asList(EOL_CRLF), asList(CUSTOM_VALUE));
|
||||
assertIteration(F, "src/config/readme.txt", asList(DELTA_UNSET));
|
||||
assertIteration(F, "src/config/windows.file", null);
|
||||
assertIteration(F, "src/config/windows.txt", asList(DELTA_UNSET));
|
||||
|
||||
assertIteration(F, "windows.file", null, asList(EOL_CRLF), null);
|
||||
assertIteration(F, "windows.txt", asList(EOL_LF), asList(EOL_CRLF),
|
||||
asList(CUSTOM_VALUE));
|
||||
assertIteration(F, "windows.file", null);
|
||||
assertIteration(F, "windows.txt", asList(EOL_LF));
|
||||
|
||||
endWalk();
|
||||
}
|
||||
|
@ -212,14 +200,11 @@ public void testNoMatchingAttributes() throws Exception {
|
|||
|
||||
private void assertIteration(FileMode type, String pathName)
|
||||
throws IOException {
|
||||
assertIteration(type, pathName, Collections.<Attribute> emptyList(),
|
||||
Collections.<Attribute> emptyList(),
|
||||
Collections.<Attribute> emptyList());
|
||||
assertIteration(type, pathName, Collections.<Attribute> emptyList());
|
||||
}
|
||||
|
||||
private void assertIteration(FileMode type, String pathName,
|
||||
List<Attribute> nodeAttrs, List<Attribute> infoAttrs,
|
||||
List<Attribute> globalAttrs)
|
||||
List<Attribute> nodeAttrs)
|
||||
throws IOException {
|
||||
assertTrue("walk has entry", walk.next());
|
||||
assertEquals(pathName, walk.getPathString());
|
||||
|
@ -227,29 +212,27 @@ private void assertIteration(FileMode type, String pathName,
|
|||
WorkingTreeIterator itr = walk.getTree(0, WorkingTreeIterator.class);
|
||||
assertNotNull("has tree", itr);
|
||||
|
||||
AttributesNode attributeNode = itr.getEntryAttributesNode();
|
||||
assertAttributeNode(pathName, attributeNode, nodeAttrs);
|
||||
AttributesNode infoAttributeNode = itr.getInfoAttributesNode();
|
||||
assertAttributeNode(pathName, infoAttributeNode, infoAttrs);
|
||||
AttributesNode globalAttributeNode = itr.getGlobalAttributesNode();
|
||||
assertAttributeNode(pathName, globalAttributeNode, globalAttrs);
|
||||
AttributesNode attributesNode = itr.getEntryAttributesNode();
|
||||
assertAttributesNode(pathName, attributesNode, nodeAttrs);
|
||||
if (D.equals(type))
|
||||
walk.enterSubtree();
|
||||
|
||||
}
|
||||
|
||||
private void assertAttributeNode(String pathName,
|
||||
AttributesNode attributeNode, List<Attribute> nodeAttrs) {
|
||||
if (attributeNode == null)
|
||||
private void assertAttributesNode(String pathName,
|
||||
AttributesNode attributesNode, List<Attribute> nodeAttrs) {
|
||||
if (attributesNode == null)
|
||||
assertTrue(nodeAttrs == null || nodeAttrs.isEmpty());
|
||||
else {
|
||||
|
||||
Map<String, Attribute> entryAttributes = new LinkedHashMap<String, Attribute>();
|
||||
attributeNode.getAttributes(pathName, false, entryAttributes);
|
||||
Attributes entryAttributes = new Attributes();
|
||||
attributesNode.getAttributes(pathName,
|
||||
false, entryAttributes);
|
||||
|
||||
if (nodeAttrs != null && !nodeAttrs.isEmpty()) {
|
||||
for (Attribute attribute : nodeAttrs) {
|
||||
assertThat(entryAttributes.values(), hasItem(attribute));
|
||||
assertThat(entryAttributes.getAll(),
|
||||
hasItem(attribute));
|
||||
}
|
||||
} else {
|
||||
assertTrue(
|
||||
|
|
|
@ -0,0 +1,866 @@
|
|||
/*
|
||||
* Copyright (C) 2014, Obeo.
|
||||
* 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.attributes;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jgit.api.Git;
|
||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||
import org.eclipse.jgit.api.errors.NoFilepatternException;
|
||||
import org.eclipse.jgit.attributes.Attribute.State;
|
||||
import org.eclipse.jgit.dircache.DirCacheIterator;
|
||||
import org.eclipse.jgit.errors.NoWorkTreeException;
|
||||
import org.eclipse.jgit.junit.JGitTestUtil;
|
||||
import org.eclipse.jgit.junit.RepositoryTestCase;
|
||||
import org.eclipse.jgit.lib.FileMode;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.treewalk.FileTreeIterator;
|
||||
import org.eclipse.jgit.treewalk.TreeWalk;
|
||||
import org.eclipse.jgit.treewalk.TreeWalk.OperationType;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Tests the attributes are correctly computed in a {@link TreeWalk}.
|
||||
*
|
||||
* @see TreeWalk#getAttributes()
|
||||
*/
|
||||
public class TreeWalkAttributeTest extends RepositoryTestCase {
|
||||
|
||||
private static final FileMode M = FileMode.MISSING;
|
||||
|
||||
private static final FileMode D = FileMode.TREE;
|
||||
|
||||
private static final FileMode F = FileMode.REGULAR_FILE;
|
||||
|
||||
private static Attribute EOL_CRLF = new Attribute("eol", "crlf");
|
||||
|
||||
private static Attribute EOL_LF = new Attribute("eol", "lf");
|
||||
|
||||
private static Attribute TEXT_SET = new Attribute("text", State.SET);
|
||||
|
||||
private static Attribute TEXT_UNSET = new Attribute("text", State.UNSET);
|
||||
|
||||
private static Attribute DELTA_UNSET = new Attribute("delta", State.UNSET);
|
||||
|
||||
private static Attribute DELTA_SET = new Attribute("delta", State.SET);
|
||||
|
||||
private static Attribute CUSTOM_GLOBAL = new Attribute("custom", "global");
|
||||
|
||||
private static Attribute CUSTOM_INFO = new Attribute("custom", "info");
|
||||
|
||||
private static Attribute CUSTOM_ROOT = new Attribute("custom", "root");
|
||||
|
||||
private static Attribute CUSTOM_PARENT = new Attribute("custom", "parent");
|
||||
|
||||
private static Attribute CUSTOM_CURRENT = new Attribute("custom", "current");
|
||||
|
||||
private static Attribute CUSTOM2_UNSET = new Attribute("custom2",
|
||||
State.UNSET);
|
||||
|
||||
private static Attribute CUSTOM2_SET = new Attribute("custom2", State.SET);
|
||||
|
||||
private TreeWalk walk;
|
||||
|
||||
private TreeWalk ci_walk;
|
||||
|
||||
private Git git;
|
||||
|
||||
private File customAttributeFile;
|
||||
|
||||
@Override
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
git = new Git(db);
|
||||
}
|
||||
|
||||
@Override
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
if (customAttributeFile != null)
|
||||
customAttributeFile.delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the attributes are computed correctly depending on the
|
||||
* operation type.
|
||||
* <p>
|
||||
* In this test we changed the content of the attribute files in the working
|
||||
* tree compared to the one in the index.
|
||||
* </p>
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws NoFilepatternException
|
||||
* @throws GitAPIException
|
||||
*/
|
||||
@Test
|
||||
public void testCheckinCheckoutDifferences() throws IOException,
|
||||
NoFilepatternException, GitAPIException {
|
||||
|
||||
writeGlobalAttributeFile("globalAttributesFile", "*.txt -custom2");
|
||||
writeAttributesFile(".git/info/attributes", "*.txt eol=crlf");
|
||||
writeAttributesFile(".gitattributes", "*.txt custom=root");
|
||||
writeAttributesFile("level1/.gitattributes", "*.txt text");
|
||||
writeAttributesFile("level1/level2/.gitattributes", "*.txt -delta");
|
||||
|
||||
writeTrashFile("l0.txt", "");
|
||||
|
||||
writeTrashFile("level1/l1.txt", "");
|
||||
|
||||
writeTrashFile("level1/level2/l2.txt", "");
|
||||
|
||||
git.add().addFilepattern(".").call();
|
||||
|
||||
beginWalk();
|
||||
|
||||
// Modify all attributes
|
||||
writeGlobalAttributeFile("globalAttributesFile", "*.txt custom2");
|
||||
writeAttributesFile(".git/info/attributes", "*.txt eol=lf");
|
||||
writeAttributesFile(".gitattributes", "*.txt custom=info");
|
||||
writeAttributesFile("level1/.gitattributes", "*.txt -text");
|
||||
writeAttributesFile("level1/level2/.gitattributes", "*.txt delta");
|
||||
|
||||
assertEntry(F, ".gitattributes");
|
||||
assertEntry(F, "l0.txt", asSet(EOL_LF, CUSTOM_INFO, CUSTOM2_SET),
|
||||
asSet(EOL_LF, CUSTOM_ROOT, CUSTOM2_SET));
|
||||
|
||||
assertEntry(D, "level1");
|
||||
assertEntry(F, "level1/.gitattributes");
|
||||
assertEntry(F, "level1/l1.txt",
|
||||
asSet(EOL_LF, CUSTOM_INFO, CUSTOM2_SET, TEXT_UNSET),
|
||||
asSet(EOL_LF, CUSTOM_ROOT, CUSTOM2_SET, TEXT_SET));
|
||||
|
||||
assertEntry(D, "level1/level2");
|
||||
assertEntry(F, "level1/level2/.gitattributes");
|
||||
assertEntry(F, "level1/level2/l2.txt",
|
||||
asSet(EOL_LF, CUSTOM_INFO, CUSTOM2_SET, TEXT_UNSET, DELTA_SET),
|
||||
asSet(EOL_LF, CUSTOM_ROOT, CUSTOM2_SET, TEXT_SET, DELTA_UNSET));
|
||||
|
||||
endWalk();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the index is used as fallback when the git attributes file
|
||||
* are missing in the working tree.
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws NoFilepatternException
|
||||
* @throws GitAPIException
|
||||
*/
|
||||
@Test
|
||||
public void testIndexOnly() throws IOException, NoFilepatternException,
|
||||
GitAPIException {
|
||||
List<File> attrFiles = new ArrayList<File>();
|
||||
attrFiles.add(writeGlobalAttributeFile("globalAttributesFile",
|
||||
"*.txt -custom2"));
|
||||
attrFiles.add(writeAttributesFile(".git/info/attributes",
|
||||
"*.txt eol=crlf"));
|
||||
attrFiles
|
||||
.add(writeAttributesFile(".gitattributes", "*.txt custom=root"));
|
||||
attrFiles
|
||||
.add(writeAttributesFile("level1/.gitattributes", "*.txt text"));
|
||||
attrFiles.add(writeAttributesFile("level1/level2/.gitattributes",
|
||||
"*.txt -delta"));
|
||||
|
||||
writeTrashFile("l0.txt", "");
|
||||
|
||||
writeTrashFile("level1/l1.txt", "");
|
||||
|
||||
writeTrashFile("level1/level2/l2.txt", "");
|
||||
|
||||
git.add().addFilepattern(".").call();
|
||||
|
||||
// Modify all attributes
|
||||
for (File attrFile : attrFiles)
|
||||
attrFile.delete();
|
||||
|
||||
beginWalk();
|
||||
|
||||
assertEntry(M, ".gitattributes");
|
||||
assertEntry(F, "l0.txt", asSet(CUSTOM_ROOT));
|
||||
|
||||
assertEntry(D, "level1");
|
||||
assertEntry(M, "level1/.gitattributes");
|
||||
assertEntry(F, "level1/l1.txt",
|
||||
|
||||
asSet(CUSTOM_ROOT, TEXT_SET));
|
||||
|
||||
assertEntry(D, "level1/level2");
|
||||
assertEntry(M, "level1/level2/.gitattributes");
|
||||
assertEntry(F, "level1/level2/l2.txt",
|
||||
|
||||
asSet(CUSTOM_ROOT, TEXT_SET, DELTA_UNSET));
|
||||
|
||||
endWalk();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that we search in the working tree for attributes although the file
|
||||
* we are currently inspecting does not exist anymore in the working tree.
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws NoFilepatternException
|
||||
* @throws GitAPIException
|
||||
*/
|
||||
@Test
|
||||
public void testIndexOnly2()
|
||||
throws IOException, NoFilepatternException, GitAPIException {
|
||||
File l2 = writeTrashFile("level1/level2/l2.txt", "");
|
||||
writeTrashFile("level1/level2/l1.txt", "");
|
||||
|
||||
git.add().addFilepattern(".").call();
|
||||
|
||||
writeAttributesFile(".gitattributes", "*.txt custom=root");
|
||||
assertTrue(l2.delete());
|
||||
|
||||
beginWalk();
|
||||
|
||||
assertEntry(F, ".gitattributes");
|
||||
assertEntry(D, "level1");
|
||||
assertEntry(D, "level1/level2");
|
||||
assertEntry(F, "level1/level2/l1.txt", asSet(CUSTOM_ROOT));
|
||||
assertEntry(M, "level1/level2/l2.txt", asSet(CUSTOM_ROOT));
|
||||
|
||||
endWalk();
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic test for git attributes.
|
||||
* <p>
|
||||
* In this use case files are present in both the working tree and the index
|
||||
* </p>
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws NoFilepatternException
|
||||
* @throws GitAPIException
|
||||
*/
|
||||
@Test
|
||||
public void testRules() throws IOException, NoFilepatternException,
|
||||
GitAPIException {
|
||||
writeAttributesFile(".git/info/attributes", "windows* eol=crlf");
|
||||
|
||||
writeAttributesFile(".gitattributes", "*.txt eol=lf");
|
||||
writeTrashFile("windows.file", "");
|
||||
writeTrashFile("windows.txt", "");
|
||||
writeTrashFile("readme.txt", "");
|
||||
|
||||
writeAttributesFile("src/config/.gitattributes", "*.txt -delta");
|
||||
writeTrashFile("src/config/readme.txt", "");
|
||||
writeTrashFile("src/config/windows.file", "");
|
||||
writeTrashFile("src/config/windows.txt", "");
|
||||
|
||||
beginWalk();
|
||||
|
||||
git.add().addFilepattern(".").call();
|
||||
|
||||
assertEntry(F, ".gitattributes");
|
||||
assertEntry(F, "readme.txt", asSet(EOL_LF));
|
||||
|
||||
assertEntry(D, "src");
|
||||
assertEntry(D, "src/config");
|
||||
assertEntry(F, "src/config/.gitattributes");
|
||||
assertEntry(F, "src/config/readme.txt", asSet(DELTA_UNSET, EOL_LF));
|
||||
assertEntry(F, "src/config/windows.file", asSet(EOL_CRLF));
|
||||
assertEntry(F, "src/config/windows.txt", asSet(DELTA_UNSET, EOL_CRLF));
|
||||
|
||||
assertEntry(F, "windows.file", asSet(EOL_CRLF));
|
||||
assertEntry(F, "windows.txt", asSet(EOL_CRLF));
|
||||
|
||||
endWalk();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that if there is no .gitattributes file in the repository
|
||||
* everything still work fine.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void testNoAttributes() throws IOException {
|
||||
writeTrashFile("l0.txt", "");
|
||||
writeTrashFile("level1/l1.txt", "");
|
||||
writeTrashFile("level1/level2/l2.txt", "");
|
||||
|
||||
beginWalk();
|
||||
|
||||
assertEntry(F, "l0.txt");
|
||||
|
||||
assertEntry(D, "level1");
|
||||
assertEntry(F, "level1/l1.txt");
|
||||
|
||||
assertEntry(D, "level1/level2");
|
||||
assertEntry(F, "level1/level2/l2.txt");
|
||||
|
||||
endWalk();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that an empty .gitattribute file does not return incorrect value.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void testEmptyGitAttributeFile() throws IOException {
|
||||
writeAttributesFile(".git/info/attributes", "");
|
||||
writeTrashFile("l0.txt", "");
|
||||
writeAttributesFile(".gitattributes", "");
|
||||
writeTrashFile("level1/l1.txt", "");
|
||||
writeTrashFile("level1/level2/l2.txt", "");
|
||||
|
||||
beginWalk();
|
||||
|
||||
assertEntry(F, ".gitattributes");
|
||||
assertEntry(F, "l0.txt");
|
||||
|
||||
assertEntry(D, "level1");
|
||||
assertEntry(F, "level1/l1.txt");
|
||||
|
||||
assertEntry(D, "level1/level2");
|
||||
assertEntry(F, "level1/level2/l2.txt");
|
||||
|
||||
endWalk();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoMatchingAttributes() throws IOException {
|
||||
writeAttributesFile(".git/info/attributes", "*.java delta");
|
||||
writeAttributesFile(".gitattributes", "*.java -delta");
|
||||
writeAttributesFile("levelA/.gitattributes", "*.java eol=lf");
|
||||
writeAttributesFile("levelB/.gitattributes", "*.txt eol=lf");
|
||||
|
||||
writeTrashFile("levelA/lA.txt", "");
|
||||
|
||||
beginWalk();
|
||||
|
||||
assertEntry(F, ".gitattributes");
|
||||
|
||||
assertEntry(D, "levelA");
|
||||
assertEntry(F, "levelA/.gitattributes");
|
||||
assertEntry(F, "levelA/lA.txt");
|
||||
|
||||
assertEntry(D, "levelB");
|
||||
assertEntry(F, "levelB/.gitattributes");
|
||||
|
||||
endWalk();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that $GIT_DIR/info/attributes file has the highest precedence.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void testPrecedenceInfo() throws IOException {
|
||||
writeGlobalAttributeFile("globalAttributesFile", "*.txt custom=global");
|
||||
writeAttributesFile(".git/info/attributes", "*.txt custom=info");
|
||||
writeAttributesFile(".gitattributes", "*.txt custom=root");
|
||||
writeAttributesFile("level1/.gitattributes", "*.txt custom=parent");
|
||||
writeAttributesFile("level1/level2/.gitattributes",
|
||||
"*.txt custom=current");
|
||||
|
||||
writeTrashFile("level1/level2/file.txt", "");
|
||||
|
||||
beginWalk();
|
||||
|
||||
assertEntry(F, ".gitattributes");
|
||||
|
||||
assertEntry(D, "level1");
|
||||
assertEntry(F, "level1/.gitattributes");
|
||||
|
||||
assertEntry(D, "level1/level2");
|
||||
assertEntry(F, "level1/level2/.gitattributes");
|
||||
assertEntry(F, "level1/level2/file.txt", asSet(CUSTOM_INFO));
|
||||
|
||||
endWalk();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that a subfolder ".gitattributes" file has precedence over its
|
||||
* parent.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void testPrecedenceCurrent() throws IOException {
|
||||
writeGlobalAttributeFile("globalAttributesFile", "*.txt custom=global");
|
||||
writeAttributesFile(".gitattributes", "*.txt custom=root");
|
||||
writeAttributesFile("level1/.gitattributes", "*.txt custom=parent");
|
||||
writeAttributesFile("level1/level2/.gitattributes",
|
||||
"*.txt custom=current");
|
||||
|
||||
writeTrashFile("level1/level2/file.txt", "");
|
||||
|
||||
beginWalk();
|
||||
|
||||
assertEntry(F, ".gitattributes");
|
||||
|
||||
assertEntry(D, "level1");
|
||||
assertEntry(F, "level1/.gitattributes");
|
||||
|
||||
assertEntry(D, "level1/level2");
|
||||
assertEntry(F, "level1/level2/.gitattributes");
|
||||
assertEntry(F, "level1/level2/file.txt", asSet(CUSTOM_CURRENT));
|
||||
|
||||
endWalk();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the parent ".gitattributes" file is used as fallback.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void testPrecedenceParent() throws IOException {
|
||||
writeGlobalAttributeFile("globalAttributesFile", "*.txt custom=global");
|
||||
writeAttributesFile(".gitattributes", "*.txt custom=root");
|
||||
writeAttributesFile("level1/.gitattributes", "*.txt custom=parent");
|
||||
|
||||
writeTrashFile("level1/level2/file.txt", "");
|
||||
|
||||
beginWalk();
|
||||
|
||||
assertEntry(F, ".gitattributes");
|
||||
|
||||
assertEntry(D, "level1");
|
||||
assertEntry(F, "level1/.gitattributes");
|
||||
|
||||
assertEntry(D, "level1/level2");
|
||||
assertEntry(F, "level1/level2/file.txt", asSet(CUSTOM_PARENT));
|
||||
|
||||
endWalk();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the grand parent ".gitattributes" file is used as fallback.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void testPrecedenceRoot() throws IOException {
|
||||
writeGlobalAttributeFile("globalAttributesFile", "*.txt custom=global");
|
||||
writeAttributesFile(".gitattributes", "*.txt custom=root");
|
||||
|
||||
writeTrashFile("level1/level2/file.txt", "");
|
||||
|
||||
beginWalk();
|
||||
|
||||
assertEntry(F, ".gitattributes");
|
||||
|
||||
assertEntry(D, "level1");
|
||||
|
||||
assertEntry(D, "level1/level2");
|
||||
assertEntry(F, "level1/level2/file.txt", asSet(CUSTOM_ROOT));
|
||||
|
||||
endWalk();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the global attribute file is used as fallback.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void testPrecedenceGlobal() throws IOException {
|
||||
writeGlobalAttributeFile("globalAttributesFile", "*.txt custom=global");
|
||||
|
||||
writeTrashFile("level1/level2/file.txt", "");
|
||||
|
||||
beginWalk();
|
||||
|
||||
assertEntry(D, "level1");
|
||||
|
||||
assertEntry(D, "level1/level2");
|
||||
assertEntry(F, "level1/level2/file.txt", asSet(CUSTOM_GLOBAL));
|
||||
|
||||
endWalk();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the precedence on a hierarchy with multiple attributes.
|
||||
* <p>
|
||||
* In this test all file are present in both the working tree and the index.
|
||||
* </p>
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws GitAPIException
|
||||
* @throws NoFilepatternException
|
||||
*/
|
||||
@Test
|
||||
public void testHierarchyBothIterator() throws IOException,
|
||||
NoFilepatternException, GitAPIException {
|
||||
writeAttributesFile(".git/info/attributes", "*.global eol=crlf");
|
||||
writeAttributesFile(".gitattributes", "*.local eol=lf");
|
||||
writeAttributesFile("level1/.gitattributes", "*.local text");
|
||||
writeAttributesFile("level1/level2/.gitattributes", "*.local -text");
|
||||
|
||||
writeTrashFile("l0.global", "");
|
||||
writeTrashFile("l0.local", "");
|
||||
|
||||
writeTrashFile("level1/l1.global", "");
|
||||
writeTrashFile("level1/l1.local", "");
|
||||
|
||||
writeTrashFile("level1/level2/l2.global", "");
|
||||
writeTrashFile("level1/level2/l2.local", "");
|
||||
|
||||
beginWalk();
|
||||
|
||||
git.add().addFilepattern(".").call();
|
||||
|
||||
assertEntry(F, ".gitattributes");
|
||||
assertEntry(F, "l0.global", asSet(EOL_CRLF));
|
||||
assertEntry(F, "l0.local", asSet(EOL_LF));
|
||||
|
||||
assertEntry(D, "level1");
|
||||
assertEntry(F, "level1/.gitattributes");
|
||||
assertEntry(F, "level1/l1.global", asSet(EOL_CRLF));
|
||||
assertEntry(F, "level1/l1.local", asSet(EOL_LF, TEXT_SET));
|
||||
|
||||
assertEntry(D, "level1/level2");
|
||||
assertEntry(F, "level1/level2/.gitattributes");
|
||||
assertEntry(F, "level1/level2/l2.global", asSet(EOL_CRLF));
|
||||
assertEntry(F, "level1/level2/l2.local", asSet(EOL_LF, TEXT_UNSET));
|
||||
|
||||
endWalk();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the precedence on a hierarchy with multiple attributes.
|
||||
* <p>
|
||||
* In this test all file are present only in the working tree.
|
||||
* </p>
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws GitAPIException
|
||||
* @throws NoFilepatternException
|
||||
*/
|
||||
@Test
|
||||
public void testHierarchyWorktreeOnly()
|
||||
throws IOException, NoFilepatternException, GitAPIException {
|
||||
writeAttributesFile(".git/info/attributes", "*.global eol=crlf");
|
||||
writeAttributesFile(".gitattributes", "*.local eol=lf");
|
||||
writeAttributesFile("level1/.gitattributes", "*.local text");
|
||||
writeAttributesFile("level1/level2/.gitattributes", "*.local -text");
|
||||
|
||||
writeTrashFile("l0.global", "");
|
||||
writeTrashFile("l0.local", "");
|
||||
|
||||
writeTrashFile("level1/l1.global", "");
|
||||
writeTrashFile("level1/l1.local", "");
|
||||
|
||||
writeTrashFile("level1/level2/l2.global", "");
|
||||
writeTrashFile("level1/level2/l2.local", "");
|
||||
|
||||
beginWalk();
|
||||
|
||||
assertEntry(F, ".gitattributes");
|
||||
assertEntry(F, "l0.global", asSet(EOL_CRLF));
|
||||
assertEntry(F, "l0.local", asSet(EOL_LF));
|
||||
|
||||
assertEntry(D, "level1");
|
||||
assertEntry(F, "level1/.gitattributes");
|
||||
assertEntry(F, "level1/l1.global", asSet(EOL_CRLF));
|
||||
assertEntry(F, "level1/l1.local", asSet(EOL_LF, TEXT_SET));
|
||||
|
||||
assertEntry(D, "level1/level2");
|
||||
assertEntry(F, "level1/level2/.gitattributes");
|
||||
assertEntry(F, "level1/level2/l2.global", asSet(EOL_CRLF));
|
||||
assertEntry(F, "level1/level2/l2.local", asSet(EOL_LF, TEXT_UNSET));
|
||||
|
||||
endWalk();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the list of attributes is an aggregation of all the
|
||||
* attributes from the attributes files hierarchy.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void testAggregation() throws IOException {
|
||||
writeGlobalAttributeFile("globalAttributesFile", "*.txt -custom2");
|
||||
writeAttributesFile(".git/info/attributes", "*.txt eol=crlf");
|
||||
writeAttributesFile(".gitattributes", "*.txt custom=root");
|
||||
writeAttributesFile("level1/.gitattributes", "*.txt text");
|
||||
writeAttributesFile("level1/level2/.gitattributes", "*.txt -delta");
|
||||
|
||||
writeTrashFile("l0.txt", "");
|
||||
|
||||
writeTrashFile("level1/l1.txt", "");
|
||||
|
||||
writeTrashFile("level1/level2/l2.txt", "");
|
||||
|
||||
beginWalk();
|
||||
|
||||
assertEntry(F, ".gitattributes");
|
||||
assertEntry(F, "l0.txt", asSet(EOL_CRLF, CUSTOM_ROOT, CUSTOM2_UNSET));
|
||||
|
||||
assertEntry(D, "level1");
|
||||
assertEntry(F, "level1/.gitattributes");
|
||||
assertEntry(F, "level1/l1.txt",
|
||||
asSet(EOL_CRLF, CUSTOM_ROOT, TEXT_SET, CUSTOM2_UNSET));
|
||||
|
||||
assertEntry(D, "level1/level2");
|
||||
assertEntry(F, "level1/level2/.gitattributes");
|
||||
assertEntry(
|
||||
F,
|
||||
"level1/level2/l2.txt",
|
||||
asSet(EOL_CRLF, CUSTOM_ROOT, TEXT_SET, DELTA_UNSET,
|
||||
CUSTOM2_UNSET));
|
||||
|
||||
endWalk();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the last entry in .gitattributes is used if 2 lines match the
|
||||
* same attribute
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void testOverriding() throws IOException {
|
||||
writeAttributesFile(".git/info/attributes",//
|
||||
//
|
||||
"*.txt custom=current",//
|
||||
"*.txt custom=parent",//
|
||||
"*.txt custom=root",//
|
||||
"*.txt custom=info",
|
||||
//
|
||||
"*.txt delta",//
|
||||
"*.txt -delta",
|
||||
//
|
||||
"*.txt eol=lf",//
|
||||
"*.txt eol=crlf",
|
||||
//
|
||||
"*.txt text",//
|
||||
"*.txt -text");
|
||||
|
||||
writeTrashFile("l0.txt", "");
|
||||
beginWalk();
|
||||
|
||||
assertEntry(F, "l0.txt",
|
||||
asSet(TEXT_UNSET, EOL_CRLF, DELTA_UNSET, CUSTOM_INFO));
|
||||
|
||||
endWalk();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the last value of an attribute is used if in the same line an
|
||||
* attribute is defined several time.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void testOverriding2() throws IOException {
|
||||
writeAttributesFile(".git/info/attributes",
|
||||
"*.txt custom=current custom=parent custom=root custom=info",//
|
||||
"*.txt delta -delta",//
|
||||
"*.txt eol=lf eol=crlf",//
|
||||
"*.txt text -text");
|
||||
writeTrashFile("l0.txt", "");
|
||||
beginWalk();
|
||||
|
||||
assertEntry(F, "l0.txt",
|
||||
asSet(TEXT_UNSET, EOL_CRLF, DELTA_UNSET, CUSTOM_INFO));
|
||||
|
||||
endWalk();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRulesInherited() throws Exception {
|
||||
writeAttributesFile(".gitattributes", "**/*.txt eol=lf");
|
||||
writeTrashFile("src/config/readme.txt", "");
|
||||
writeTrashFile("src/config/windows.file", "");
|
||||
|
||||
beginWalk();
|
||||
|
||||
assertEntry(F, ".gitattributes");
|
||||
assertEntry(D, "src");
|
||||
assertEntry(D, "src/config");
|
||||
|
||||
assertEntry(F, "src/config/readme.txt", asSet(EOL_LF));
|
||||
assertEntry(F, "src/config/windows.file",
|
||||
Collections.<Attribute> emptySet());
|
||||
|
||||
endWalk();
|
||||
}
|
||||
|
||||
private void beginWalk() throws NoWorkTreeException, IOException {
|
||||
walk = new TreeWalk(db);
|
||||
walk.addTree(new FileTreeIterator(db));
|
||||
walk.addTree(new DirCacheIterator(db.readDirCache()));
|
||||
|
||||
ci_walk = new TreeWalk(db);
|
||||
ci_walk.setOperationType(OperationType.CHECKIN_OP);
|
||||
ci_walk.addTree(new FileTreeIterator(db));
|
||||
ci_walk.addTree(new DirCacheIterator(db.readDirCache()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert an entry in which checkin and checkout attributes are expected to
|
||||
* be the same.
|
||||
*
|
||||
* @param type
|
||||
* @param pathName
|
||||
* @param forBothOperaiton
|
||||
* @throws IOException
|
||||
*/
|
||||
private void assertEntry(FileMode type, String pathName,
|
||||
Set<Attribute> forBothOperaiton) throws IOException {
|
||||
assertEntry(type, pathName, forBothOperaiton, forBothOperaiton);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert an entry with no attribute expected.
|
||||
*
|
||||
* @param type
|
||||
* @param pathName
|
||||
* @throws IOException
|
||||
*/
|
||||
private void assertEntry(FileMode type, String pathName) throws IOException {
|
||||
assertEntry(type, pathName, Collections.<Attribute> emptySet(),
|
||||
Collections.<Attribute> emptySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that an entry;
|
||||
* <ul>
|
||||
* <li>Has the correct type</li>
|
||||
* <li>Exist in the tree walk</li>
|
||||
* <li>Has the expected attributes on a checkin operation</li>
|
||||
* <li>Has the expected attributes on a checkout operation</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param type
|
||||
* @param pathName
|
||||
* @param checkinAttributes
|
||||
* @param checkoutAttributes
|
||||
* @throws IOException
|
||||
*/
|
||||
private void assertEntry(FileMode type, String pathName,
|
||||
Set<Attribute> checkinAttributes, Set<Attribute> checkoutAttributes)
|
||||
throws IOException {
|
||||
assertTrue("walk has entry", walk.next());
|
||||
assertTrue("walk has entry", ci_walk.next());
|
||||
assertEquals(pathName, walk.getPathString());
|
||||
assertEquals(type, walk.getFileMode(0));
|
||||
|
||||
assertEquals(checkinAttributes,
|
||||
asSet(ci_walk.getAttributes().getAll()));
|
||||
assertEquals(checkoutAttributes,
|
||||
asSet(walk.getAttributes().getAll()));
|
||||
|
||||
if (D.equals(type)) {
|
||||
walk.enterSubtree();
|
||||
ci_walk.enterSubtree();
|
||||
}
|
||||
}
|
||||
|
||||
private static Set<Attribute> asSet(Collection<Attribute> attributes) {
|
||||
Set<Attribute> ret = new HashSet<Attribute>();
|
||||
for (Attribute a : attributes) {
|
||||
ret.add(a);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
private File writeAttributesFile(String name, String... rules)
|
||||
throws IOException {
|
||||
StringBuilder data = new StringBuilder();
|
||||
for (String line : rules)
|
||||
data.append(line + "\n");
|
||||
return writeTrashFile(name, data.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an attributes file and set its location in the git configuration.
|
||||
*
|
||||
* @param fileName
|
||||
* @param attributes
|
||||
* @return The attribute file
|
||||
* @throws IOException
|
||||
* @see Repository#getConfig()
|
||||
*/
|
||||
private File writeGlobalAttributeFile(String fileName, String... attributes)
|
||||
throws IOException {
|
||||
customAttributeFile = File.createTempFile("tmp_", fileName, null);
|
||||
customAttributeFile.deleteOnExit();
|
||||
StringBuilder attributesFileContent = new StringBuilder();
|
||||
for (String attr : attributes) {
|
||||
attributesFileContent.append(attr).append("\n");
|
||||
}
|
||||
JGitTestUtil.write(customAttributeFile,
|
||||
attributesFileContent.toString());
|
||||
db.getConfig().setString("core", null, "attributesfile",
|
||||
customAttributeFile.getAbsolutePath());
|
||||
return customAttributeFile;
|
||||
}
|
||||
|
||||
static Set<Attribute> asSet(Attribute... attrs) {
|
||||
HashSet<Attribute> result = new HashSet<Attribute>();
|
||||
for (Attribute attr : attrs)
|
||||
result.add(attr);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void endWalk() throws IOException {
|
||||
assertFalse("Not all files tested", walk.next());
|
||||
assertFalse("Not all files tested", ci_walk.next());
|
||||
}
|
||||
}
|
|
@ -48,6 +48,7 @@
|
|||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jgit.diff.DiffEntry.ChangeType;
|
||||
|
@ -226,6 +227,19 @@ public void testExactRename_OneDeleteManyAdds() throws Exception {
|
|||
assertCopy(d, b, 100, entries.get(2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExactRename_UnstagedFile() throws Exception {
|
||||
ObjectId aId = blob("foo");
|
||||
DiffEntry a = DiffEntry.delete(PATH_A, aId);
|
||||
DiffEntry b = DiffEntry.add(PATH_B, aId);
|
||||
|
||||
rd.addAll(Arrays.asList(a, b));
|
||||
List<DiffEntry> entries = rd.compute();
|
||||
|
||||
assertEquals(1, entries.size());
|
||||
assertRename(a, b, 100, entries.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInexactRename_OnePair() throws Exception {
|
||||
ObjectId aId = blob("foo\nbar\nbaz\nblarg\n");
|
||||
|
@ -429,6 +443,23 @@ public void testNoRenames_SymlinkAndFileSamePath() throws Exception {
|
|||
assertSame(b, entries.get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoRenames_UntrackedFile() throws Exception {
|
||||
ObjectId aId = blob("foo");
|
||||
ObjectId bId = ObjectId
|
||||
.fromString("3049eb6eee7e1318f4e78e799bf33f1e54af9cbf");
|
||||
|
||||
DiffEntry a = DiffEntry.delete(PATH_A, aId);
|
||||
DiffEntry b = DiffEntry.add(PATH_B, bId);
|
||||
|
||||
rd.addAll(Arrays.asList(a, b));
|
||||
List<DiffEntry> entries = rd.compute();
|
||||
|
||||
assertEquals(2, entries.size());
|
||||
assertSame(a, entries.get(0));
|
||||
assertSame(b, entries.get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBreakModify_BreakAll() throws Exception {
|
||||
ObjectId aId = blob("foo");
|
||||
|
|
|
@ -69,9 +69,9 @@ public void testIsValidPath() {
|
|||
assertFalse(isValidPath("a\u0000b"));
|
||||
}
|
||||
|
||||
private static boolean isValidPath(final String path) {
|
||||
private static boolean isValidPath(String path) {
|
||||
try {
|
||||
DirCacheCheckout.checkValidPath(path);
|
||||
new DirCacheEntry(path);
|
||||
return true;
|
||||
} catch (InvalidPathException e) {
|
||||
return false;
|
||||
|
|
|
@ -77,7 +77,7 @@ public void looseRefPacked() throws Exception {
|
|||
tr.lightweightTag("t", a);
|
||||
|
||||
gc.packRefs();
|
||||
assertSame(repo.getRef("t").getStorage(), Storage.PACKED);
|
||||
assertSame(repo.exactRef("refs/tags/t").getStorage(), Storage.PACKED);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -126,8 +126,8 @@ public void whileRefLockedRefNotPackedNoError()
|
|||
refLock.unlock();
|
||||
}
|
||||
|
||||
assertSame(repo.getRef("refs/tags/t1").getStorage(), Storage.LOOSE);
|
||||
assertSame(repo.getRef("refs/tags/t2").getStorage(), Storage.PACKED);
|
||||
assertSame(repo.exactRef("refs/tags/t1").getStorage(), Storage.LOOSE);
|
||||
assertSame(repo.exactRef("refs/tags/t2").getStorage(), Storage.PACKED);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -146,7 +146,7 @@ public void whileRefUpdatedRefUpdateSucceeds()
|
|||
public Result call() throws Exception {
|
||||
RefUpdate update = new RefDirectoryUpdate(
|
||||
(RefDirectory) repo.getRefDatabase(),
|
||||
repo.getRef("refs/tags/t")) {
|
||||
repo.exactRef("refs/tags/t")) {
|
||||
@Override
|
||||
public boolean isForceUpdate() {
|
||||
try {
|
||||
|
@ -182,7 +182,7 @@ public Void call() throws Exception {
|
|||
pool.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
assertEquals(repo.getRef("refs/tags/t").getObjectId(), b);
|
||||
assertEquals(repo.exactRef("refs/tags/t").getObjectId(), b);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -194,23 +194,23 @@ public void dontPackHEAD_nonBare() throws Exception {
|
|||
|
||||
// check for the unborn branch master. HEAD should point to master and
|
||||
// master doesn't exist.
|
||||
assertEquals(repo.getRef("HEAD").getTarget().getName(),
|
||||
assertEquals(repo.exactRef("HEAD").getTarget().getName(),
|
||||
"refs/heads/master");
|
||||
assertNull(repo.getRef("HEAD").getTarget().getObjectId());
|
||||
assertNull(repo.exactRef("HEAD").getTarget().getObjectId());
|
||||
gc.packRefs();
|
||||
assertSame(repo.getRef("HEAD").getStorage(), Storage.LOOSE);
|
||||
assertEquals(repo.getRef("HEAD").getTarget().getName(),
|
||||
assertSame(repo.exactRef("HEAD").getStorage(), Storage.LOOSE);
|
||||
assertEquals(repo.exactRef("HEAD").getTarget().getName(),
|
||||
"refs/heads/master");
|
||||
assertNull(repo.getRef("HEAD").getTarget().getObjectId());
|
||||
assertNull(repo.exactRef("HEAD").getTarget().getObjectId());
|
||||
|
||||
git.checkout().setName("refs/heads/side").call();
|
||||
gc.packRefs();
|
||||
assertSame(repo.getRef("HEAD").getStorage(), Storage.LOOSE);
|
||||
assertSame(repo.exactRef("HEAD").getStorage(), Storage.LOOSE);
|
||||
|
||||
// check for detached HEAD
|
||||
git.checkout().setName(first.getName()).call();
|
||||
gc.packRefs();
|
||||
assertSame(repo.getRef("HEAD").getStorage(), Storage.LOOSE);
|
||||
assertSame(repo.exactRef("HEAD").getStorage(), Storage.LOOSE);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -229,20 +229,20 @@ public void dontPackHEAD_bare() throws Exception {
|
|||
|
||||
// check for the unborn branch master. HEAD should point to master and
|
||||
// master doesn't exist.
|
||||
assertEquals(repo.getRef("HEAD").getTarget().getName(),
|
||||
assertEquals(repo.exactRef("HEAD").getTarget().getName(),
|
||||
"refs/heads/master");
|
||||
assertNull(repo.getRef("HEAD").getTarget().getObjectId());
|
||||
assertNull(repo.exactRef("HEAD").getTarget().getObjectId());
|
||||
gc.packRefs();
|
||||
assertSame(repo.getRef("HEAD").getStorage(), Storage.LOOSE);
|
||||
assertEquals(repo.getRef("HEAD").getTarget().getName(),
|
||||
assertSame(repo.exactRef("HEAD").getStorage(), Storage.LOOSE);
|
||||
assertEquals(repo.exactRef("HEAD").getTarget().getName(),
|
||||
"refs/heads/master");
|
||||
assertNull(repo.getRef("HEAD").getTarget().getObjectId());
|
||||
assertNull(repo.exactRef("HEAD").getTarget().getObjectId());
|
||||
|
||||
// check for non-detached HEAD
|
||||
repo.updateRef(Constants.HEAD).link("refs/heads/side");
|
||||
gc.packRefs();
|
||||
assertSame(repo.getRef("HEAD").getStorage(), Storage.LOOSE);
|
||||
assertEquals(repo.getRef("HEAD").getTarget().getObjectId(),
|
||||
assertSame(repo.exactRef("HEAD").getStorage(), Storage.LOOSE);
|
||||
assertEquals(repo.exactRef("HEAD").getTarget().getObjectId(),
|
||||
second.getId());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -857,6 +857,36 @@ public void testGetRefs_CycleInSymbolicRef() throws IOException {
|
|||
assertNull("mising 1 due to cycle", r);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRef_CycleInSymbolicRef() throws IOException {
|
||||
Ref r;
|
||||
|
||||
writeLooseRef("refs/1", "ref: refs/2\n");
|
||||
writeLooseRef("refs/2", "ref: refs/3\n");
|
||||
writeLooseRef("refs/3", "ref: refs/4\n");
|
||||
writeLooseRef("refs/4", "ref: refs/5\n");
|
||||
writeLooseRef("refs/5", "ref: refs/end\n");
|
||||
writeLooseRef("refs/end", A);
|
||||
|
||||
r = refdir.getRef("1");
|
||||
assertEquals("refs/1", r.getName());
|
||||
assertEquals(A, r.getObjectId());
|
||||
assertTrue(r.isSymbolic());
|
||||
|
||||
writeLooseRef("refs/5", "ref: refs/6\n");
|
||||
writeLooseRef("refs/6", "ref: refs/end\n");
|
||||
|
||||
r = refdir.getRef("1");
|
||||
assertNull("missing 1 due to cycle", r);
|
||||
|
||||
writeLooseRef("refs/heads/1", B);
|
||||
|
||||
r = refdir.getRef("1");
|
||||
assertEquals("refs/heads/1", r.getName());
|
||||
assertEquals(B, r.getObjectId());
|
||||
assertFalse(r.isSymbolic());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRefs_PackedNotPeeled_Sorted() throws IOException {
|
||||
Map<String, Ref> all;
|
||||
|
@ -1024,6 +1054,25 @@ public void testGetRef_EmptyDatabase() throws IOException {
|
|||
assertNull(refdir.getRef("v1.0"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExactRef_EmptyDatabase() throws IOException {
|
||||
Ref r;
|
||||
|
||||
r = refdir.exactRef(HEAD);
|
||||
assertTrue(r.isSymbolic());
|
||||
assertSame(LOOSE, r.getStorage());
|
||||
assertEquals("refs/heads/master", r.getTarget().getName());
|
||||
assertSame(NEW, r.getTarget().getStorage());
|
||||
assertNull(r.getTarget().getObjectId());
|
||||
|
||||
assertNull(refdir.exactRef("refs/heads/master"));
|
||||
assertNull(refdir.exactRef("refs/tags/v1.0"));
|
||||
assertNull(refdir.exactRef("FETCH_HEAD"));
|
||||
assertNull(refdir.exactRef("NOT.A.REF.NAME"));
|
||||
assertNull(refdir.exactRef("master"));
|
||||
assertNull(refdir.exactRef("v1.0"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRef_FetchHead() throws IOException {
|
||||
// This is an odd special case where we need to make sure we read
|
||||
|
|
|
@ -347,7 +347,7 @@ public void testUpdateRefDetached() throws Exception {
|
|||
Result update = updateRef.update();
|
||||
assertEquals(Result.FORCED, update);
|
||||
assertEquals(ppid, db.resolve("HEAD"));
|
||||
Ref ref = db.getRef("HEAD");
|
||||
Ref ref = db.exactRef("HEAD");
|
||||
assertEquals("HEAD", ref.getName());
|
||||
assertTrue("is detached", !ref.isSymbolic());
|
||||
|
||||
|
@ -377,7 +377,7 @@ public void testUpdateRefDetachedUnbornHead() throws Exception {
|
|||
Result update = updateRef.update();
|
||||
assertEquals(Result.NEW, update);
|
||||
assertEquals(ppid, db.resolve("HEAD"));
|
||||
Ref ref = db.getRef("HEAD");
|
||||
Ref ref = db.exactRef("HEAD");
|
||||
assertEquals("HEAD", ref.getName());
|
||||
assertTrue("is detached", !ref.isSymbolic());
|
||||
|
||||
|
@ -681,13 +681,13 @@ public void testRenameCurrentBranch() throws IOException {
|
|||
public void testRenameBranchAlsoInPack() throws IOException {
|
||||
ObjectId rb = db.resolve("refs/heads/b");
|
||||
ObjectId rb2 = db.resolve("refs/heads/b~1");
|
||||
assertEquals(Ref.Storage.PACKED, db.getRef("refs/heads/b").getStorage());
|
||||
assertEquals(Ref.Storage.PACKED, db.exactRef("refs/heads/b").getStorage());
|
||||
RefUpdate updateRef = db.updateRef("refs/heads/b");
|
||||
updateRef.setNewObjectId(rb2);
|
||||
updateRef.setForceUpdate(true);
|
||||
Result update = updateRef.update();
|
||||
assertEquals("internal check new ref is loose", Result.FORCED, update);
|
||||
assertEquals(Ref.Storage.LOOSE, db.getRef("refs/heads/b").getStorage());
|
||||
assertEquals(Ref.Storage.LOOSE, db.exactRef("refs/heads/b").getStorage());
|
||||
writeReflog(db, rb, "Just a message", "refs/heads/b");
|
||||
assertTrue("log on old branch", new File(db.getDirectory(),
|
||||
"logs/refs/heads/b").exists());
|
||||
|
|
|
@ -127,25 +127,25 @@ public void insertExplicitChangeId() throws Exception {
|
|||
@Test
|
||||
public void resetFromSymref() throws Exception {
|
||||
repo.updateRef("HEAD").link("refs/heads/master");
|
||||
Ref head = repo.getRef("HEAD");
|
||||
Ref head = repo.exactRef("HEAD");
|
||||
RevCommit master = tr.branch("master").commit().create();
|
||||
RevCommit branch = tr.branch("branch").commit().create();
|
||||
RevCommit detached = tr.commit().create();
|
||||
|
||||
assertTrue(head.isSymbolic());
|
||||
assertEquals("refs/heads/master", head.getTarget().getName());
|
||||
assertEquals(master, repo.getRef("refs/heads/master").getObjectId());
|
||||
assertEquals(branch, repo.getRef("refs/heads/branch").getObjectId());
|
||||
assertEquals(master, repo.exactRef("refs/heads/master").getObjectId());
|
||||
assertEquals(branch, repo.exactRef("refs/heads/branch").getObjectId());
|
||||
|
||||
// Reset to branches preserves symref.
|
||||
tr.reset("master");
|
||||
head = repo.getRef("HEAD");
|
||||
head = repo.exactRef("HEAD");
|
||||
assertEquals(master, head.getObjectId());
|
||||
assertTrue(head.isSymbolic());
|
||||
assertEquals("refs/heads/master", head.getTarget().getName());
|
||||
|
||||
tr.reset("branch");
|
||||
head = repo.getRef("HEAD");
|
||||
head = repo.exactRef("HEAD");
|
||||
assertEquals(branch, head.getObjectId());
|
||||
assertTrue(head.isSymbolic());
|
||||
assertEquals("refs/heads/master", head.getTarget().getName());
|
||||
|
@ -153,50 +153,50 @@ public void resetFromSymref() throws Exception {
|
|||
|
||||
// Reset to a SHA-1 detaches.
|
||||
tr.reset(detached);
|
||||
head = repo.getRef("HEAD");
|
||||
head = repo.exactRef("HEAD");
|
||||
assertEquals(detached, head.getObjectId());
|
||||
assertFalse(head.isSymbolic());
|
||||
|
||||
tr.reset(detached.name());
|
||||
head = repo.getRef("HEAD");
|
||||
head = repo.exactRef("HEAD");
|
||||
assertEquals(detached, head.getObjectId());
|
||||
assertFalse(head.isSymbolic());
|
||||
|
||||
// Reset back to a branch remains detached.
|
||||
tr.reset("master");
|
||||
head = repo.getRef("HEAD");
|
||||
head = repo.exactRef("HEAD");
|
||||
assertEquals(lastHeadBeforeDetach, head.getObjectId());
|
||||
assertFalse(head.isSymbolic());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resetFromDetachedHead() throws Exception {
|
||||
Ref head = repo.getRef("HEAD");
|
||||
Ref head = repo.exactRef("HEAD");
|
||||
RevCommit master = tr.branch("master").commit().create();
|
||||
RevCommit branch = tr.branch("branch").commit().create();
|
||||
RevCommit detached = tr.commit().create();
|
||||
|
||||
assertNull(head);
|
||||
assertEquals(master, repo.getRef("refs/heads/master").getObjectId());
|
||||
assertEquals(branch, repo.getRef("refs/heads/branch").getObjectId());
|
||||
assertEquals(master, repo.exactRef("refs/heads/master").getObjectId());
|
||||
assertEquals(branch, repo.exactRef("refs/heads/branch").getObjectId());
|
||||
|
||||
tr.reset("master");
|
||||
head = repo.getRef("HEAD");
|
||||
head = repo.exactRef("HEAD");
|
||||
assertEquals(master, head.getObjectId());
|
||||
assertFalse(head.isSymbolic());
|
||||
|
||||
tr.reset("branch");
|
||||
head = repo.getRef("HEAD");
|
||||
head = repo.exactRef("HEAD");
|
||||
assertEquals(branch, head.getObjectId());
|
||||
assertFalse(head.isSymbolic());
|
||||
|
||||
tr.reset(detached);
|
||||
head = repo.getRef("HEAD");
|
||||
head = repo.exactRef("HEAD");
|
||||
assertEquals(detached, head.getObjectId());
|
||||
assertFalse(head.isSymbolic());
|
||||
|
||||
tr.reset(detached.name());
|
||||
head = repo.getRef("HEAD");
|
||||
head = repo.exactRef("HEAD");
|
||||
assertEquals(detached, head.getObjectId());
|
||||
assertFalse(head.isSymbolic());
|
||||
}
|
||||
|
@ -222,7 +222,7 @@ public void amendRef() throws Exception {
|
|||
.tick(3)
|
||||
.add("bar", "fixed bar contents")
|
||||
.create();
|
||||
assertEquals(amended, repo.getRef("refs/heads/master").getObjectId());
|
||||
assertEquals(amended, repo.exactRef("refs/heads/master").getObjectId());
|
||||
rw.parseBody(amended);
|
||||
|
||||
assertEquals(1, amended.getParentCount());
|
||||
|
@ -257,7 +257,7 @@ public void amendHead() throws Exception {
|
|||
.add("foo", "fixed foo contents")
|
||||
.create();
|
||||
|
||||
Ref head = repo.getRef(Constants.HEAD);
|
||||
Ref head = repo.exactRef(Constants.HEAD);
|
||||
assertEquals(amended, head.getObjectId());
|
||||
assertTrue(head.isSymbolic());
|
||||
assertEquals("refs/heads/master", head.getTarget().getName());
|
||||
|
@ -291,7 +291,7 @@ public void amendCommit() throws Exception {
|
|||
public void commitToUnbornHead() throws Exception {
|
||||
repo.updateRef("HEAD").link("refs/heads/master");
|
||||
RevCommit root = tr.branch("HEAD").commit().create();
|
||||
Ref ref = repo.getRef(Constants.HEAD);
|
||||
Ref ref = repo.exactRef(Constants.HEAD);
|
||||
assertEquals(root, ref.getObjectId());
|
||||
assertTrue(ref.isSymbolic());
|
||||
assertEquals("refs/heads/master", ref.getTarget().getName());
|
||||
|
@ -316,7 +316,7 @@ public void cherryPick() throws Exception {
|
|||
RevCommit result = tr.cherryPick(toPick);
|
||||
rw.parseBody(result);
|
||||
|
||||
Ref headRef = tr.getRepository().getRef("HEAD");
|
||||
Ref headRef = tr.getRepository().exactRef("HEAD");
|
||||
assertEquals(result, headRef.getObjectId());
|
||||
assertTrue(headRef.isSymbolic());
|
||||
assertEquals("refs/heads/master", headRef.getLeaf().getName());
|
||||
|
@ -371,7 +371,7 @@ public void cherryPickWithIdenticalContents() throws Exception {
|
|||
.create();
|
||||
assertNotEquals(head, toPick);
|
||||
assertNull(tr.cherryPick(toPick));
|
||||
assertEquals(head, repo.getRef("HEAD").getObjectId());
|
||||
assertEquals(head, repo.exactRef("HEAD").getObjectId());
|
||||
}
|
||||
|
||||
private String blobAsString(AnyObjectId treeish, String path)
|
||||
|
|
|
@ -79,6 +79,7 @@
|
|||
import org.eclipse.jgit.treewalk.TreeWalk;
|
||||
import org.eclipse.jgit.util.FS;
|
||||
import org.eclipse.jgit.util.FileUtils;
|
||||
import org.junit.Assume;
|
||||
import org.junit.Test;
|
||||
|
||||
public class DirCacheCheckoutTest extends RepositoryTestCase {
|
||||
|
@ -112,7 +113,7 @@ private List<String> getRemoved() {
|
|||
return dco.getRemoved();
|
||||
}
|
||||
|
||||
private Map<String, ObjectId> getUpdated() {
|
||||
private Map<String, String> getUpdated() {
|
||||
return dco.getUpdated();
|
||||
}
|
||||
|
||||
|
@ -267,8 +268,6 @@ private void assertIndex(HashMap<String, String> i)
|
|||
@Test
|
||||
public void testRules1thru3_NoIndexEntry() throws IOException {
|
||||
ObjectId head = buildTree(mk("foo"));
|
||||
TreeWalk tw = TreeWalk.forPath(db, "foo", head);
|
||||
ObjectId objectId = tw.getObjectId(0);
|
||||
ObjectId merge = db.newObjectInserter().insert(Constants.OBJ_TREE,
|
||||
new byte[0]);
|
||||
|
||||
|
@ -278,10 +277,9 @@ public void testRules1thru3_NoIndexEntry() throws IOException {
|
|||
|
||||
prescanTwoTrees(merge, head);
|
||||
|
||||
assertEquals(objectId, getUpdated().get("foo"));
|
||||
assertTrue(getUpdated().containsKey("foo"));
|
||||
|
||||
merge = buildTree(mkmap("foo", "a"));
|
||||
tw = TreeWalk.forPath(db, "foo", merge);
|
||||
|
||||
prescanTwoTrees(head, merge);
|
||||
|
||||
|
@ -925,6 +923,7 @@ public void testCheckoutOutChanges() throws IOException {
|
|||
|
||||
@Test
|
||||
public void testCheckoutChangeLinkToEmptyDir() throws Exception {
|
||||
Assume.assumeTrue(FS.DETECTED.supportsSymlinks());
|
||||
String fname = "was_file";
|
||||
Git git = Git.wrap(db);
|
||||
|
||||
|
@ -961,6 +960,7 @@ public void testCheckoutChangeLinkToEmptyDir() throws Exception {
|
|||
|
||||
@Test
|
||||
public void testCheckoutChangeLinkToEmptyDirs() throws Exception {
|
||||
Assume.assumeTrue(FS.DETECTED.supportsSymlinks());
|
||||
String fname = "was_file";
|
||||
Git git = Git.wrap(db);
|
||||
|
||||
|
@ -999,6 +999,7 @@ public void testCheckoutChangeLinkToEmptyDirs() throws Exception {
|
|||
|
||||
@Test
|
||||
public void testCheckoutChangeLinkToNonEmptyDirs() throws Exception {
|
||||
Assume.assumeTrue(FS.DETECTED.supportsSymlinks());
|
||||
String fname = "file";
|
||||
Git git = Git.wrap(db);
|
||||
|
||||
|
@ -1043,6 +1044,7 @@ public void testCheckoutChangeLinkToNonEmptyDirs() throws Exception {
|
|||
@Test
|
||||
public void testCheckoutChangeLinkToNonEmptyDirsAndNewIndexEntry()
|
||||
throws Exception {
|
||||
Assume.assumeTrue(FS.DETECTED.supportsSymlinks());
|
||||
String fname = "file";
|
||||
Git git = Git.wrap(db);
|
||||
|
||||
|
@ -1364,6 +1366,7 @@ public void testOverwriteUntrackedFileModeChange()
|
|||
@Test
|
||||
public void testOverwriteUntrackedLinkModeChange()
|
||||
throws Exception {
|
||||
Assume.assumeTrue(FS.DETECTED.supportsSymlinks());
|
||||
String fname = "file.txt";
|
||||
Git git = Git.wrap(db);
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ public void setUp() throws Exception {
|
|||
.call();
|
||||
|
||||
submodule_db = (FileRepository) Git.wrap(db).submoduleAdd()
|
||||
.setPath("submodule")
|
||||
.setPath("modules/submodule")
|
||||
.setURI(submoduleStandalone.getDirectory().toURI().toString())
|
||||
.call();
|
||||
submoduleStandalone.close();
|
||||
|
|
|
@ -163,7 +163,7 @@ public void testReadAllIncludingSymrefs() throws Exception {
|
|||
@Test
|
||||
public void testReadSymRefToPacked() throws IOException {
|
||||
writeSymref("HEAD", "refs/heads/b");
|
||||
Ref ref = db.getRef("HEAD");
|
||||
Ref ref = db.exactRef("HEAD");
|
||||
assertEquals(Ref.Storage.LOOSE, ref.getStorage());
|
||||
assertTrue("is symref", ref.isSymbolic());
|
||||
ref = ref.getTarget();
|
||||
|
@ -181,7 +181,7 @@ public void testReadSymRefToLoosePacked() throws IOException {
|
|||
assertEquals(Result.FORCED, update); // internal
|
||||
|
||||
writeSymref("HEAD", "refs/heads/master");
|
||||
Ref ref = db.getRef("HEAD");
|
||||
Ref ref = db.exactRef("HEAD");
|
||||
assertEquals(Ref.Storage.LOOSE, ref.getStorage());
|
||||
ref = ref.getTarget();
|
||||
assertEquals("refs/heads/master", ref.getName());
|
||||
|
@ -194,13 +194,13 @@ public void testReadLooseRef() throws IOException {
|
|||
updateRef.setNewObjectId(db.resolve("refs/heads/master"));
|
||||
Result update = updateRef.update();
|
||||
assertEquals(Result.NEW, update);
|
||||
Ref ref = db.getRef("ref/heads/new");
|
||||
Ref ref = db.exactRef("ref/heads/new");
|
||||
assertEquals(Storage.LOOSE, ref.getStorage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetShortRef() throws IOException {
|
||||
Ref ref = db.getRef("master");
|
||||
Ref ref = db.exactRef("refs/heads/master");
|
||||
assertEquals("refs/heads/master", ref.getName());
|
||||
assertEquals(db.resolve("refs/heads/master"), ref.getObjectId());
|
||||
}
|
||||
|
@ -222,7 +222,7 @@ public void testRefsUnderRefs() throws IOException {
|
|||
|
||||
assertNull(db.getRefDatabase().exactRef("refs/foo/bar"));
|
||||
|
||||
Ref ref = db.getRef("refs/foo/bar");
|
||||
Ref ref = db.findRef("refs/foo/bar");
|
||||
assertEquals("refs/heads/refs/foo/bar", ref.getName());
|
||||
assertEquals(db.resolve("refs/heads/master"), ref.getObjectId());
|
||||
}
|
||||
|
@ -237,7 +237,7 @@ public void testAmbiguousRefsUnderRefs() throws IOException {
|
|||
assertEquals("refs/foo/bar", exactRef.getName());
|
||||
assertEquals(masterId, exactRef.getObjectId());
|
||||
|
||||
Ref ref = db.getRef("refs/foo/bar");
|
||||
Ref ref = db.findRef("refs/foo/bar");
|
||||
assertEquals("refs/foo/bar", ref.getName());
|
||||
assertEquals(masterId, ref.getObjectId());
|
||||
}
|
||||
|
@ -251,7 +251,7 @@ public void testAmbiguousRefsUnderRefs() throws IOException {
|
|||
@Test
|
||||
public void testReadLoosePackedRef() throws IOException,
|
||||
InterruptedException {
|
||||
Ref ref = db.getRef("refs/heads/master");
|
||||
Ref ref = db.exactRef("refs/heads/master");
|
||||
assertEquals(Storage.PACKED, ref.getStorage());
|
||||
FileOutputStream os = new FileOutputStream(new File(db.getDirectory(),
|
||||
"refs/heads/master"));
|
||||
|
@ -259,7 +259,7 @@ public void testReadLoosePackedRef() throws IOException,
|
|||
os.write('\n');
|
||||
os.close();
|
||||
|
||||
ref = db.getRef("refs/heads/master");
|
||||
ref = db.exactRef("refs/heads/master");
|
||||
assertEquals(Storage.LOOSE, ref.getStorage());
|
||||
}
|
||||
|
||||
|
@ -271,7 +271,7 @@ public void testReadLoosePackedRef() throws IOException,
|
|||
*/
|
||||
@Test
|
||||
public void testReadSimplePackedRefSameRepo() throws IOException {
|
||||
Ref ref = db.getRef("refs/heads/master");
|
||||
Ref ref = db.exactRef("refs/heads/master");
|
||||
ObjectId pid = db.resolve("refs/heads/master^");
|
||||
assertEquals(Storage.PACKED, ref.getStorage());
|
||||
RefUpdate updateRef = db.updateRef("refs/heads/master");
|
||||
|
@ -280,19 +280,19 @@ public void testReadSimplePackedRefSameRepo() throws IOException {
|
|||
Result update = updateRef.update();
|
||||
assertEquals(Result.FORCED, update);
|
||||
|
||||
ref = db.getRef("refs/heads/master");
|
||||
ref = db.exactRef("refs/heads/master");
|
||||
assertEquals(Storage.LOOSE, ref.getStorage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResolvedNamesBranch() throws IOException {
|
||||
Ref ref = db.getRef("a");
|
||||
Ref ref = db.findRef("a");
|
||||
assertEquals("refs/heads/a", ref.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResolvedSymRef() throws IOException {
|
||||
Ref ref = db.getRef(Constants.HEAD);
|
||||
Ref ref = db.exactRef(Constants.HEAD);
|
||||
assertEquals(Constants.HEAD, ref.getName());
|
||||
assertTrue("is symbolic ref", ref.isSymbolic());
|
||||
assertSame(Ref.Storage.LOOSE, ref.getStorage());
|
||||
|
|
|
@ -84,44 +84,44 @@ public void setUp() throws Exception {
|
|||
|
||||
@Test
|
||||
public void testOneBranch() throws IOException {
|
||||
Ref a = db.getRef("refs/heads/a");
|
||||
Ref master = db.getRef("refs/heads/master");
|
||||
Ref a = db.exactRef("refs/heads/a");
|
||||
Ref master = db.exactRef("refs/heads/master");
|
||||
String message = formatter.format(Arrays.asList(a), master);
|
||||
assertEquals("Merge branch 'a'", message);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTwoBranches() throws IOException {
|
||||
Ref a = db.getRef("refs/heads/a");
|
||||
Ref b = db.getRef("refs/heads/b");
|
||||
Ref master = db.getRef("refs/heads/master");
|
||||
Ref a = db.exactRef("refs/heads/a");
|
||||
Ref b = db.exactRef("refs/heads/b");
|
||||
Ref master = db.exactRef("refs/heads/master");
|
||||
String message = formatter.format(Arrays.asList(a, b), master);
|
||||
assertEquals("Merge branches 'a' and 'b'", message);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThreeBranches() throws IOException {
|
||||
Ref c = db.getRef("refs/heads/c");
|
||||
Ref b = db.getRef("refs/heads/b");
|
||||
Ref a = db.getRef("refs/heads/a");
|
||||
Ref master = db.getRef("refs/heads/master");
|
||||
Ref c = db.exactRef("refs/heads/c");
|
||||
Ref b = db.exactRef("refs/heads/b");
|
||||
Ref a = db.exactRef("refs/heads/a");
|
||||
Ref master = db.exactRef("refs/heads/master");
|
||||
String message = formatter.format(Arrays.asList(c, b, a), master);
|
||||
assertEquals("Merge branches 'c', 'b' and 'a'", message);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoteBranch() throws Exception {
|
||||
Ref remoteA = db.getRef("refs/remotes/origin/remote-a");
|
||||
Ref master = db.getRef("refs/heads/master");
|
||||
Ref remoteA = db.exactRef("refs/remotes/origin/remote-a");
|
||||
Ref master = db.exactRef("refs/heads/master");
|
||||
String message = formatter.format(Arrays.asList(remoteA), master);
|
||||
assertEquals("Merge remote-tracking branch 'origin/remote-a'", message);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMixed() throws IOException {
|
||||
Ref c = db.getRef("refs/heads/c");
|
||||
Ref remoteA = db.getRef("refs/remotes/origin/remote-a");
|
||||
Ref master = db.getRef("refs/heads/master");
|
||||
Ref c = db.exactRef("refs/heads/c");
|
||||
Ref remoteA = db.exactRef("refs/remotes/origin/remote-a");
|
||||
Ref master = db.exactRef("refs/heads/master");
|
||||
String message = formatter.format(Arrays.asList(c, remoteA), master);
|
||||
assertEquals("Merge branch 'c', remote-tracking branch 'origin/remote-a'",
|
||||
message);
|
||||
|
@ -129,8 +129,8 @@ public void testMixed() throws IOException {
|
|||
|
||||
@Test
|
||||
public void testTag() throws IOException {
|
||||
Ref tagA = db.getRef("refs/tags/A");
|
||||
Ref master = db.getRef("refs/heads/master");
|
||||
Ref tagA = db.exactRef("refs/tags/A");
|
||||
Ref master = db.exactRef("refs/heads/master");
|
||||
String message = formatter.format(Arrays.asList(tagA), master);
|
||||
assertEquals("Merge tag 'A'", message);
|
||||
}
|
||||
|
@ -141,7 +141,7 @@ public void testCommit() throws IOException {
|
|||
.fromString("6db9c2ebf75590eef973081736730a9ea169a0c4");
|
||||
Ref commit = new ObjectIdRef.Unpeeled(Storage.LOOSE,
|
||||
objectId.getName(), objectId);
|
||||
Ref master = db.getRef("refs/heads/master");
|
||||
Ref master = db.exactRef("refs/heads/master");
|
||||
String message = formatter.format(Arrays.asList(commit), master);
|
||||
assertEquals("Merge commit '6db9c2ebf75590eef973081736730a9ea169a0c4'",
|
||||
message);
|
||||
|
@ -154,7 +154,7 @@ public void testPullWithUri() throws IOException {
|
|||
.fromString("6db9c2ebf75590eef973081736730a9ea169a0c4");
|
||||
Ref remoteBranch = new ObjectIdRef.Unpeeled(Storage.LOOSE, name,
|
||||
objectId);
|
||||
Ref master = db.getRef("refs/heads/master");
|
||||
Ref master = db.exactRef("refs/heads/master");
|
||||
String message = formatter.format(Arrays.asList(remoteBranch), master);
|
||||
assertEquals("Merge branch 'test' of http://egit.eclipse.org/jgit.git",
|
||||
message);
|
||||
|
@ -162,16 +162,16 @@ public void testPullWithUri() throws IOException {
|
|||
|
||||
@Test
|
||||
public void testIntoOtherThanMaster() throws IOException {
|
||||
Ref a = db.getRef("refs/heads/a");
|
||||
Ref b = db.getRef("refs/heads/b");
|
||||
Ref a = db.exactRef("refs/heads/a");
|
||||
Ref b = db.exactRef("refs/heads/b");
|
||||
String message = formatter.format(Arrays.asList(a), b);
|
||||
assertEquals("Merge branch 'a' into b", message);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntoHeadOtherThanMaster() throws IOException {
|
||||
Ref a = db.getRef("refs/heads/a");
|
||||
Ref b = db.getRef("refs/heads/b");
|
||||
Ref a = db.exactRef("refs/heads/a");
|
||||
Ref b = db.exactRef("refs/heads/b");
|
||||
SymbolicRef head = new SymbolicRef("HEAD", b);
|
||||
String message = formatter.format(Arrays.asList(a), head);
|
||||
assertEquals("Merge branch 'a' into b", message);
|
||||
|
@ -179,8 +179,8 @@ public void testIntoHeadOtherThanMaster() throws IOException {
|
|||
|
||||
@Test
|
||||
public void testIntoSymbolicRefHeadPointingToMaster() throws IOException {
|
||||
Ref a = db.getRef("refs/heads/a");
|
||||
Ref master = db.getRef("refs/heads/master");
|
||||
Ref a = db.exactRef("refs/heads/a");
|
||||
Ref master = db.exactRef("refs/heads/master");
|
||||
SymbolicRef head = new SymbolicRef("HEAD", master);
|
||||
String message = formatter.format(Arrays.asList(a), head);
|
||||
assertEquals("Merge branch 'a'", message);
|
||||
|
|
|
@ -630,7 +630,7 @@ public void checkMergeCrissCross(MergeStrategy strategy) throws Exception {
|
|||
// ResolveMerge
|
||||
try {
|
||||
MergeResult mergeResult = git.merge().setStrategy(strategy)
|
||||
.include(git.getRepository().getRef("refs/heads/side"))
|
||||
.include(git.getRepository().exactRef("refs/heads/side"))
|
||||
.call();
|
||||
assertEquals(MergeStrategy.RECURSIVE, strategy);
|
||||
assertEquals(MergeResult.MergeStatus.MERGED,
|
||||
|
|
|
@ -76,7 +76,7 @@ public void testCommit() throws Exception {
|
|||
Git git = new Git(db);
|
||||
revCommit = git.commit().setMessage("squash_me").call();
|
||||
|
||||
Ref master = db.getRef("refs/heads/master");
|
||||
Ref master = db.exactRef("refs/heads/master");
|
||||
String message = msgFormatter.format(Arrays.asList(revCommit), master);
|
||||
assertEquals(
|
||||
"Squashed commit of the following:\n\ncommit "
|
||||
|
|
|
@ -0,0 +1,200 @@
|
|||
/*
|
||||
* Copyright (C) 2015, Google Inc.
|
||||
* 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.transport;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jgit.errors.TransportException;
|
||||
import org.eclipse.jgit.internal.JGitText;
|
||||
import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
|
||||
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
|
||||
import org.eclipse.jgit.lib.Constants;
|
||||
import org.eclipse.jgit.lib.NullProgressMonitor;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.eclipse.jgit.lib.ObjectInserter;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.transport.resolver.ReceivePackFactory;
|
||||
import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
|
||||
import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class AtomicPushTest {
|
||||
private URIish uri;
|
||||
private TestProtocol<Object> testProtocol;
|
||||
private Object ctx = new Object();
|
||||
private InMemoryRepository server;
|
||||
private InMemoryRepository client;
|
||||
private ObjectId obj1;
|
||||
private ObjectId obj2;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
server = newRepo("server");
|
||||
client = newRepo("client");
|
||||
testProtocol = new TestProtocol<>(
|
||||
null,
|
||||
new ReceivePackFactory<Object>() {
|
||||
@Override
|
||||
public ReceivePack create(Object req, Repository db)
|
||||
throws ServiceNotEnabledException,
|
||||
ServiceNotAuthorizedException {
|
||||
return new ReceivePack(db);
|
||||
}
|
||||
});
|
||||
uri = testProtocol.register(ctx, server);
|
||||
|
||||
try (ObjectInserter ins = client.newObjectInserter()) {
|
||||
obj1 = ins.insert(Constants.OBJ_BLOB, Constants.encode("test"));
|
||||
obj2 = ins.insert(Constants.OBJ_BLOB, Constants.encode("file"));
|
||||
ins.flush();
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
Transport.unregister(testProtocol);
|
||||
}
|
||||
|
||||
private static InMemoryRepository newRepo(String name) {
|
||||
return new InMemoryRepository(new DfsRepositoryDescription(name));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pushNonAtomic() throws Exception {
|
||||
PushResult r;
|
||||
server.setPerformsAtomicTransactions(false);
|
||||
Transport tn = testProtocol.open(uri, client, "server");
|
||||
try {
|
||||
tn.setPushAtomic(false);
|
||||
r = tn.push(NullProgressMonitor.INSTANCE, commands());
|
||||
} finally {
|
||||
tn.close();
|
||||
}
|
||||
|
||||
RemoteRefUpdate one = r.getRemoteUpdate("refs/heads/one");
|
||||
RemoteRefUpdate two = r.getRemoteUpdate("refs/heads/two");
|
||||
assertSame(RemoteRefUpdate.Status.OK, one.getStatus());
|
||||
assertSame(
|
||||
RemoteRefUpdate.Status.REJECTED_REMOTE_CHANGED,
|
||||
two.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pushAtomicClientGivesUpEarly() throws Exception {
|
||||
PushResult r;
|
||||
Transport tn = testProtocol.open(uri, client, "server");
|
||||
try {
|
||||
tn.setPushAtomic(true);
|
||||
r = tn.push(NullProgressMonitor.INSTANCE, commands());
|
||||
} finally {
|
||||
tn.close();
|
||||
}
|
||||
|
||||
RemoteRefUpdate one = r.getRemoteUpdate("refs/heads/one");
|
||||
RemoteRefUpdate two = r.getRemoteUpdate("refs/heads/two");
|
||||
assertSame(
|
||||
RemoteRefUpdate.Status.REJECTED_OTHER_REASON,
|
||||
one.getStatus());
|
||||
assertSame(
|
||||
RemoteRefUpdate.Status.REJECTED_REMOTE_CHANGED,
|
||||
two.getStatus());
|
||||
assertEquals(JGitText.get().transactionAborted, one.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pushAtomicDisabled() throws Exception {
|
||||
List<RemoteRefUpdate> cmds = new ArrayList<>();
|
||||
cmds.add(new RemoteRefUpdate(
|
||||
null, null,
|
||||
obj1, "refs/heads/one",
|
||||
true /* force update */,
|
||||
null /* no local tracking ref */,
|
||||
ObjectId.zeroId()));
|
||||
cmds.add(new RemoteRefUpdate(
|
||||
null, null,
|
||||
obj2, "refs/heads/two",
|
||||
true /* force update */,
|
||||
null /* no local tracking ref */,
|
||||
ObjectId.zeroId()));
|
||||
|
||||
server.setPerformsAtomicTransactions(false);
|
||||
Transport tn = testProtocol.open(uri, client, "server");
|
||||
try {
|
||||
tn.setPushAtomic(true);
|
||||
tn.push(NullProgressMonitor.INSTANCE, cmds);
|
||||
fail("did not throw TransportException");
|
||||
} catch (TransportException e) {
|
||||
assertEquals(
|
||||
uri + ": " + JGitText.get().atomicPushNotSupported,
|
||||
e.getMessage());
|
||||
} finally {
|
||||
tn.close();
|
||||
}
|
||||
}
|
||||
|
||||
private List<RemoteRefUpdate> commands() throws IOException {
|
||||
List<RemoteRefUpdate> cmds = new ArrayList<>();
|
||||
cmds.add(new RemoteRefUpdate(
|
||||
null, null,
|
||||
obj1, "refs/heads/one",
|
||||
true /* force update */,
|
||||
null /* no local tracking ref */,
|
||||
ObjectId.zeroId()));
|
||||
cmds.add(new RemoteRefUpdate(
|
||||
null, null,
|
||||
obj2, "refs/heads/two",
|
||||
true /* force update */,
|
||||
null /* no local tracking ref */,
|
||||
obj1));
|
||||
return cmds;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
* Copyright (C) 2015, Google Inc.
|
||||
* 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.transport;
|
||||
|
||||
import static org.eclipse.jgit.transport.RemoteRefUpdate.Status.REJECTED_OTHER_REASON;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
|
||||
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
|
||||
import org.eclipse.jgit.lib.Constants;
|
||||
import org.eclipse.jgit.lib.NullProgressMonitor;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.eclipse.jgit.lib.ObjectInserter;
|
||||
import org.eclipse.jgit.lib.RefUpdate;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.transport.resolver.ReceivePackFactory;
|
||||
import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
|
||||
import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class PushConnectionTest {
|
||||
private URIish uri;
|
||||
private TestProtocol<Object> testProtocol;
|
||||
private Object ctx = new Object();
|
||||
private InMemoryRepository server;
|
||||
private InMemoryRepository client;
|
||||
private ObjectId obj1;
|
||||
private ObjectId obj2;
|
||||
private ObjectId obj3;
|
||||
private String refName = "refs/tags/blob";
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
server = newRepo("server");
|
||||
client = newRepo("client");
|
||||
testProtocol = new TestProtocol<>(
|
||||
null,
|
||||
new ReceivePackFactory<Object>() {
|
||||
@Override
|
||||
public ReceivePack create(Object req, Repository db)
|
||||
throws ServiceNotEnabledException,
|
||||
ServiceNotAuthorizedException {
|
||||
return new ReceivePack(db);
|
||||
}
|
||||
});
|
||||
uri = testProtocol.register(ctx, server);
|
||||
|
||||
try (ObjectInserter ins = server.newObjectInserter()) {
|
||||
obj1 = ins.insert(Constants.OBJ_BLOB, Constants.encode("test"));
|
||||
obj3 = ins.insert(Constants.OBJ_BLOB, Constants.encode("not"));
|
||||
ins.flush();
|
||||
|
||||
RefUpdate u = server.updateRef(refName);
|
||||
u.setNewObjectId(obj1);
|
||||
assertEquals(RefUpdate.Result.NEW, u.update());
|
||||
}
|
||||
|
||||
try (ObjectInserter ins = client.newObjectInserter()) {
|
||||
obj2 = ins.insert(Constants.OBJ_BLOB, Constants.encode("file"));
|
||||
ins.flush();
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
Transport.unregister(testProtocol);
|
||||
}
|
||||
|
||||
private static InMemoryRepository newRepo(String name) {
|
||||
return new InMemoryRepository(new DfsRepositoryDescription(name));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWrongOldIdDoesNotReplace() throws IOException {
|
||||
RemoteRefUpdate rru = new RemoteRefUpdate(null, null, obj2, refName,
|
||||
false, null, obj3);
|
||||
|
||||
Map<String, RemoteRefUpdate> updates = new HashMap<>();
|
||||
updates.put(rru.getRemoteName(), rru);
|
||||
|
||||
Transport tn = testProtocol.open(uri, client, "server");
|
||||
try {
|
||||
PushConnection connection = tn.openPush();
|
||||
try {
|
||||
connection.push(NullProgressMonitor.INSTANCE, updates);
|
||||
} finally {
|
||||
connection.close();
|
||||
}
|
||||
} finally {
|
||||
tn.close();
|
||||
}
|
||||
|
||||
assertEquals(REJECTED_OTHER_REASON, rru.getStatus());
|
||||
assertEquals("invalid old id sent", rru.getMessage());
|
||||
}
|
||||
}
|
|
@ -125,7 +125,7 @@ public void testFetch() throws Exception {
|
|||
.setRefSpecs(HEADS)
|
||||
.call();
|
||||
assertEquals(master,
|
||||
local.getRepository().getRef("master").getObjectId());
|
||||
local.getRepository().exactRef("refs/heads/master").getObjectId());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -142,7 +142,7 @@ public void testPush() throws Exception {
|
|||
.setRefSpecs(HEADS)
|
||||
.call();
|
||||
assertEquals(master,
|
||||
remote.getRepository().getRef("master").getObjectId());
|
||||
remote.getRepository().exactRef("refs/heads/master").getObjectId());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -177,7 +177,7 @@ public UploadPack create(User req, Repository db)
|
|||
// Expected.
|
||||
}
|
||||
assertEquals(1, rejected.get());
|
||||
assertNull(local.getRepository().getRef("master"));
|
||||
assertNull(local.getRepository().exactRef("refs/heads/master"));
|
||||
|
||||
git.fetch()
|
||||
.setRemote(user2Uri.toString())
|
||||
|
@ -185,7 +185,7 @@ public UploadPack create(User req, Repository db)
|
|||
.call();
|
||||
assertEquals(1, rejected.get());
|
||||
assertEquals(master,
|
||||
local.getRepository().getRef("master").getObjectId());
|
||||
local.getRepository().exactRef("refs/heads/master").getObjectId());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -222,7 +222,7 @@ public ReceivePack create(User req, Repository db)
|
|||
JGitText.get().pushNotPermitted));
|
||||
}
|
||||
assertEquals(1, rejected.get());
|
||||
assertNull(remote.getRepository().getRef("master"));
|
||||
assertNull(remote.getRepository().exactRef("refs/heads/master"));
|
||||
|
||||
git.push()
|
||||
.setRemote(user2Uri.toString())
|
||||
|
@ -230,7 +230,7 @@ public ReceivePack create(User req, Repository db)
|
|||
.call();
|
||||
assertEquals(1, rejected.get());
|
||||
assertEquals(master,
|
||||
remote.getRepository().getRef("master").getObjectId());
|
||||
remote.getRepository().exactRef("refs/heads/master").getObjectId());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -928,4 +928,19 @@ public void testALot() throws URISyntaxException {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringConstructor() throws Exception {
|
||||
String str = "http://example.com/";
|
||||
URIish u = new URIish(str);
|
||||
assertEquals("example.com", u.getHost());
|
||||
assertEquals("/", u.getPath());
|
||||
assertEquals(str, u.toString());
|
||||
|
||||
str = "http://example.com";
|
||||
u = new URIish(str);
|
||||
assertEquals("example.com", u.getHost());
|
||||
assertEquals("", u.getPath());
|
||||
assertEquals(str, u.toString());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,6 +43,20 @@
|
|||
|
||||
package org.eclipse.jgit.transport;
|
||||
|
||||
import static org.eclipse.jgit.transport.WalkEncryptionTest.Util.UTF_8;
|
||||
import static org.eclipse.jgit.transport.WalkEncryptionTest.Util.cryptoCipherListPBE;
|
||||
import static org.eclipse.jgit.transport.WalkEncryptionTest.Util.cryptoCipherListTrans;
|
||||
import static org.eclipse.jgit.transport.WalkEncryptionTest.Util.folderDelete;
|
||||
import static org.eclipse.jgit.transport.WalkEncryptionTest.Util.permitLongTests;
|
||||
import static org.eclipse.jgit.transport.WalkEncryptionTest.Util.policySetup;
|
||||
import static org.eclipse.jgit.transport.WalkEncryptionTest.Util.product;
|
||||
import static org.eclipse.jgit.transport.WalkEncryptionTest.Util.proxySetup;
|
||||
import static org.eclipse.jgit.transport.WalkEncryptionTest.Util.publicAddress;
|
||||
import static org.eclipse.jgit.transport.WalkEncryptionTest.Util.reportPolicy;
|
||||
import static org.eclipse.jgit.transport.WalkEncryptionTest.Util.securityProviderName;
|
||||
import static org.eclipse.jgit.transport.WalkEncryptionTest.Util.textWrite;
|
||||
import static org.eclipse.jgit.transport.WalkEncryptionTest.Util.transferStream;
|
||||
import static org.eclipse.jgit.transport.WalkEncryptionTest.Util.verifyFileContent;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
@ -59,7 +73,10 @@
|
|||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
import java.security.GeneralSecurityException;
|
||||
|
@ -94,8 +111,6 @@
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static org.eclipse.jgit.transport.WalkEncryptionTest.Util.*;
|
||||
|
||||
/**
|
||||
* Amazon S3 encryption pipeline test.
|
||||
*
|
||||
|
@ -401,14 +416,22 @@ static void folderDelete(String folder) throws Exception {
|
|||
* @throws Exception
|
||||
*/
|
||||
static String publicAddress() throws Exception {
|
||||
String service = "http://checkip.amazonaws.com";
|
||||
URL url = new URL(service);
|
||||
BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader(url.openStream()));
|
||||
try {
|
||||
return reader.readLine();
|
||||
} finally {
|
||||
reader.close();
|
||||
String service = "http://checkip.amazonaws.com";
|
||||
URL url = new URL(service);
|
||||
URLConnection c = url.openConnection();
|
||||
c.setConnectTimeout(500);
|
||||
c.setReadTimeout(500);
|
||||
BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader(c.getInputStream()));
|
||||
try {
|
||||
return reader.readLine();
|
||||
} finally {
|
||||
reader.close();
|
||||
}
|
||||
} catch (UnknownHostException | SocketTimeoutException e) {
|
||||
return "Can't reach http://checkip.amazonaws.com to"
|
||||
+ " determine public address";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,8 @@
|
|||
|
||||
package org.eclipse.jgit.treewalk;
|
||||
|
||||
import static org.eclipse.jgit.lib.FileMode.REGULAR_FILE;
|
||||
import static org.eclipse.jgit.lib.FileMode.SYMLINK;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertSame;
|
||||
|
@ -50,9 +52,11 @@
|
|||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
import org.eclipse.jgit.errors.CorruptObjectException;
|
||||
import org.eclipse.jgit.lib.Constants;
|
||||
import org.eclipse.jgit.lib.FileMode;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.eclipse.jgit.lib.TreeFormatter;
|
||||
import org.eclipse.jgit.util.RawParseUtils;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
@ -369,4 +373,41 @@ public void testFreakingHugePathName() throws Exception {
|
|||
assertEquals(name, RawParseUtils.decode(Constants.CHARSET, ctp.path,
|
||||
ctp.pathOffset, ctp.pathLen));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindAttributesWhenFirst() throws CorruptObjectException {
|
||||
TreeFormatter tree = new TreeFormatter();
|
||||
tree.append(".gitattributes", REGULAR_FILE, hash_a);
|
||||
ctp.reset(tree.toByteArray());
|
||||
|
||||
assertTrue(ctp.findFile(".gitattributes"));
|
||||
assertEquals(REGULAR_FILE.getBits(), ctp.getEntryRawMode());
|
||||
assertEquals(".gitattributes", ctp.getEntryPathString());
|
||||
assertEquals(hash_a, ctp.getEntryObjectId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindAttributesWhenSecond() throws CorruptObjectException {
|
||||
TreeFormatter tree = new TreeFormatter();
|
||||
tree.append(".config", SYMLINK, hash_a);
|
||||
tree.append(".gitattributes", REGULAR_FILE, hash_foo);
|
||||
ctp.reset(tree.toByteArray());
|
||||
|
||||
assertTrue(ctp.findFile(".gitattributes"));
|
||||
assertEquals(REGULAR_FILE.getBits(), ctp.getEntryRawMode());
|
||||
assertEquals(".gitattributes", ctp.getEntryPathString());
|
||||
assertEquals(hash_foo, ctp.getEntryObjectId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindAttributesWhenMissing() throws CorruptObjectException {
|
||||
TreeFormatter tree = new TreeFormatter();
|
||||
tree.append("src", REGULAR_FILE, hash_a);
|
||||
tree.append("zoo", REGULAR_FILE, hash_foo);
|
||||
ctp.reset(tree.toByteArray());
|
||||
|
||||
assertFalse(ctp.findFile(".gitattributes"));
|
||||
assertEquals(11, ctp.idOffset()); // Did not walk the entire tree.
|
||||
assertEquals("src", ctp.getEntryPathString());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,6 +67,7 @@
|
|||
public class FileTreeIteratorJava7Test extends RepositoryTestCase {
|
||||
@Test
|
||||
public void testFileModeSymLinkIsNotATree() throws IOException {
|
||||
org.junit.Assume.assumeTrue(FS.DETECTED.supportsSymlinks());
|
||||
FS fs = db.getFS();
|
||||
// mål = target in swedish, just to get som unicode in here
|
||||
writeTrashFile("mål/data", "targetdata");
|
||||
|
@ -163,6 +164,7 @@ public void apply(DirCacheEntry ent) {
|
|||
*/
|
||||
@Test
|
||||
public void testSymlinkActuallyModified() throws Exception {
|
||||
org.junit.Assume.assumeTrue(FS.DETECTED.supportsSymlinks());
|
||||
final String NORMALIZED = "target";
|
||||
final byte[] NORMALIZED_BYTES = Constants.encode(NORMALIZED);
|
||||
try (ObjectInserter oi = db.newObjectInserter()) {
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
public class TreeWalkJava7Test extends RepositoryTestCase {
|
||||
@Test
|
||||
public void testSymlinkToDirNotRecursingViaSymlink() throws Exception {
|
||||
org.junit.Assume.assumeTrue(FS.DETECTED.supportsSymlinks());
|
||||
FS fs = db.getFS();
|
||||
assertTrue(fs.supportsSymlinks());
|
||||
writeTrashFile("target/data", "targetdata");
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
|
||||
import org.eclipse.jgit.junit.RepositoryTestCase;
|
||||
import org.junit.After;
|
||||
import org.junit.Assume;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -87,6 +88,7 @@ public void tearDown() throws Exception {
|
|||
*/
|
||||
@Test
|
||||
public void testSymlinkAttributes() throws IOException, InterruptedException {
|
||||
Assume.assumeTrue(FS.DETECTED.supportsSymlinks());
|
||||
FS fs = FS.DETECTED;
|
||||
File link = new File(trash, "ä");
|
||||
File target = new File(trash, "å");
|
||||
|
|
|
@ -73,6 +73,7 @@ public void tearDown() throws Exception {
|
|||
@Test
|
||||
public void testDeleteSymlinkToDirectoryDoesNotDeleteTarget()
|
||||
throws IOException {
|
||||
org.junit.Assume.assumeTrue(FS.DETECTED.supportsSymlinks());
|
||||
FS fs = FS.DETECTED;
|
||||
File dir = new File(trash, "dir");
|
||||
File file = new File(dir, "file");
|
||||
|
|
|
@ -92,11 +92,9 @@ public void testFailedCommitMsgHookBlocksCommit() throws Exception {
|
|||
fail("expected commit-msg hook to abort commit");
|
||||
} catch (AbortedByHookException e) {
|
||||
assertEquals("unexpected error message from commit-msg hook",
|
||||
"Rejected by \"commit-msg\" hook.\nstderr"
|
||||
+ System.lineSeparator(),
|
||||
"Rejected by \"commit-msg\" hook.\nstderr\n",
|
||||
e.getMessage());
|
||||
assertEquals("unexpected output from commit-msg hook",
|
||||
"test" + System.lineSeparator(),
|
||||
assertEquals("unexpected output from commit-msg hook", "test\n",
|
||||
out.toString());
|
||||
}
|
||||
}
|
||||
|
@ -114,7 +112,7 @@ public void testCommitMsgHookReceivesCorrectParameter() throws Exception {
|
|||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
git.commit().setMessage("commit")
|
||||
.setHookOutputStream(new PrintStream(out)).call();
|
||||
assertEquals(".git/COMMIT_EDITMSG" + System.lineSeparator(),
|
||||
assertEquals(".git/COMMIT_EDITMSG\n",
|
||||
out.toString("UTF-8"));
|
||||
}
|
||||
|
||||
|
@ -147,11 +145,10 @@ public void testRunHook() throws Exception {
|
|||
new String[] {
|
||||
"arg1", "arg2" },
|
||||
new PrintStream(out), new PrintStream(err), "stdin");
|
||||
assertEquals("unexpected hook output", "test arg1 arg2"
|
||||
+ System.lineSeparator() + "stdin" + System.lineSeparator(),
|
||||
|
||||
assertEquals("unexpected hook output", "test arg1 arg2\nstdin\n",
|
||||
out.toString("UTF-8"));
|
||||
assertEquals("unexpected output on stderr stream",
|
||||
"stderr" + System.lineSeparator(),
|
||||
assertEquals("unexpected output on stderr stream", "stderr\n",
|
||||
err.toString("UTF-8"));
|
||||
assertEquals("unexpected exit code", 0, res.getExitCode());
|
||||
assertEquals("unexpected process status", ProcessResult.Status.OK,
|
||||
|
@ -175,11 +172,9 @@ public void testFailedPreCommitHookBlockCommit() throws Exception {
|
|||
fail("expected pre-commit hook to abort commit");
|
||||
} catch (AbortedByHookException e) {
|
||||
assertEquals("unexpected error message from pre-commit hook",
|
||||
"Rejected by \"pre-commit\" hook.\nstderr"
|
||||
+ System.lineSeparator(),
|
||||
"Rejected by \"pre-commit\" hook.\nstderr\n",
|
||||
e.getMessage());
|
||||
assertEquals("unexpected output from pre-commit hook",
|
||||
"test" + System.lineSeparator(),
|
||||
assertEquals("unexpected output from pre-commit hook", "test\n",
|
||||
out.toString());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,16 +52,17 @@
|
|||
import java.io.InputStream;
|
||||
|
||||
import org.eclipse.jgit.junit.JGitTestUtil;
|
||||
import org.eclipse.jgit.util.FS.ExecutionResult;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class RunExternalScriptTest {
|
||||
private static final String LF = "\n";
|
||||
|
||||
private ByteArrayOutputStream out;
|
||||
|
||||
private ByteArrayOutputStream err;
|
||||
|
||||
private String sep = System.getProperty("line.separator");
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
out = new ByteArrayOutputStream();
|
||||
|
@ -73,7 +74,7 @@ public void testCopyStdIn() throws IOException, InterruptedException {
|
|||
String inputStr = "a\nb\rc\r\nd";
|
||||
File script = writeTempFile("cat -");
|
||||
int rc = FS.DETECTED.runProcess(
|
||||
new ProcessBuilder("/bin/sh", script.getPath()), out, err,
|
||||
new ProcessBuilder("sh", script.getPath()), out, err,
|
||||
new ByteArrayInputStream(inputStr.getBytes()));
|
||||
assertEquals(0, rc);
|
||||
assertEquals(inputStr, new String(out.toByteArray()));
|
||||
|
@ -84,7 +85,7 @@ public void testCopyStdIn() throws IOException, InterruptedException {
|
|||
public void testCopyNullStdIn() throws IOException, InterruptedException {
|
||||
File script = writeTempFile("cat -");
|
||||
int rc = FS.DETECTED.runProcess(
|
||||
new ProcessBuilder("/bin/sh", script.getPath()), out, err,
|
||||
new ProcessBuilder("sh", script.getPath()), out, err,
|
||||
(InputStream) null);
|
||||
assertEquals(0, rc);
|
||||
assertEquals("", new String(out.toByteArray()));
|
||||
|
@ -94,7 +95,8 @@ public void testCopyNullStdIn() throws IOException, InterruptedException {
|
|||
@Test
|
||||
public void testArguments() throws IOException, InterruptedException {
|
||||
File script = writeTempFile("echo $#,$1,$2,$3,$4,$5,$6");
|
||||
int rc = FS.DETECTED.runProcess(new ProcessBuilder("/bin/bash",
|
||||
int rc = FS.DETECTED.runProcess(
|
||||
new ProcessBuilder("sh",
|
||||
script.getPath(), "a", "b", "c"), out, err, (InputStream) null);
|
||||
assertEquals(0, rc);
|
||||
assertEquals("3,a,b,c,,,\n", new String(out.toByteArray()));
|
||||
|
@ -105,7 +107,7 @@ public void testArguments() throws IOException, InterruptedException {
|
|||
public void testRc() throws IOException, InterruptedException {
|
||||
File script = writeTempFile("exit 3");
|
||||
int rc = FS.DETECTED.runProcess(
|
||||
new ProcessBuilder("/bin/sh", script.getPath(), "a", "b", "c"),
|
||||
new ProcessBuilder("sh", script.getPath(), "a", "b", "c"),
|
||||
out, err, (InputStream) null);
|
||||
assertEquals(3, rc);
|
||||
assertEquals("", new String(out.toByteArray()));
|
||||
|
@ -116,7 +118,7 @@ public void testRc() throws IOException, InterruptedException {
|
|||
public void testNullStdout() throws IOException, InterruptedException {
|
||||
File script = writeTempFile("echo hi");
|
||||
int rc = FS.DETECTED.runProcess(
|
||||
new ProcessBuilder("/bin/sh", script.getPath()), null, err,
|
||||
new ProcessBuilder("sh", script.getPath()), null, err,
|
||||
(InputStream) null);
|
||||
assertEquals(0, rc);
|
||||
assertEquals("", new String(out.toByteArray()));
|
||||
|
@ -127,11 +129,11 @@ public void testNullStdout() throws IOException, InterruptedException {
|
|||
public void testStdErr() throws IOException, InterruptedException {
|
||||
File script = writeTempFile("echo hi >&2");
|
||||
int rc = FS.DETECTED.runProcess(
|
||||
new ProcessBuilder("/bin/sh", script.getPath()), null, err,
|
||||
new ProcessBuilder("sh", script.getPath()), null, err,
|
||||
(InputStream) null);
|
||||
assertEquals(0, rc);
|
||||
assertEquals("", new String(out.toByteArray()));
|
||||
assertEquals("hi" + sep, new String(err.toByteArray()));
|
||||
assertEquals("hi" + LF, new String(err.toByteArray()));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -139,11 +141,11 @@ public void testAllTogetherBin() throws IOException, InterruptedException {
|
|||
String inputStr = "a\nb\rc\r\nd";
|
||||
File script = writeTempFile("echo $#,$1,$2,$3,$4,$5,$6 >&2 ; cat -; exit 5");
|
||||
int rc = FS.DETECTED.runProcess(
|
||||
new ProcessBuilder("/bin/sh", script.getPath(), "a", "b", "c"),
|
||||
new ProcessBuilder("sh", script.getPath(), "a", "b", "c"),
|
||||
out, err, new ByteArrayInputStream(inputStr.getBytes()));
|
||||
assertEquals(5, rc);
|
||||
assertEquals(inputStr, new String(out.toByteArray()));
|
||||
assertEquals("3,a,b,c,,," + sep, new String(err.toByteArray()));
|
||||
assertEquals("3,a,b,c,,," + LF, new String(err.toByteArray()));
|
||||
}
|
||||
|
||||
@Test(expected = IOException.class)
|
||||
|
@ -158,11 +160,50 @@ public void testWrongSh() throws IOException, InterruptedException {
|
|||
public void testWrongScript() throws IOException, InterruptedException {
|
||||
File script = writeTempFile("cat-foo -");
|
||||
int rc = FS.DETECTED.runProcess(
|
||||
new ProcessBuilder("/bin/sh", script.getPath(), "a", "b", "c"),
|
||||
new ProcessBuilder("sh", script.getPath(), "a", "b", "c"),
|
||||
out, err, (InputStream) null);
|
||||
assertEquals(127, rc);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCopyStdInExecute()
|
||||
throws IOException, InterruptedException {
|
||||
String inputStr = "a\nb\rc\r\nd";
|
||||
File script = writeTempFile("cat -");
|
||||
ProcessBuilder pb = new ProcessBuilder("sh", script.getPath());
|
||||
ExecutionResult res = FS.DETECTED.execute(pb,
|
||||
new ByteArrayInputStream(inputStr.getBytes()));
|
||||
assertEquals(0, res.getRc());
|
||||
assertEquals(inputStr, new String(res.getStdout().toByteArray()));
|
||||
assertEquals("", new String(res.getStderr().toByteArray()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStdErrExecute() throws IOException, InterruptedException {
|
||||
File script = writeTempFile("echo hi >&2");
|
||||
ProcessBuilder pb = new ProcessBuilder("sh", script.getPath());
|
||||
ExecutionResult res = FS.DETECTED.execute(pb, null);
|
||||
assertEquals(0, res.getRc());
|
||||
assertEquals("", new String(res.getStdout().toByteArray()));
|
||||
assertEquals("hi" + LF, new String(res.getStderr().toByteArray()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllTogetherBinExecute()
|
||||
throws IOException, InterruptedException {
|
||||
String inputStr = "a\nb\rc\r\nd";
|
||||
File script = writeTempFile(
|
||||
"echo $#,$1,$2,$3,$4,$5,$6 >&2 ; cat -; exit 5");
|
||||
ProcessBuilder pb = new ProcessBuilder("sh", script.getPath(), "a",
|
||||
"b", "c");
|
||||
ExecutionResult res = FS.DETECTED.execute(pb,
|
||||
new ByteArrayInputStream(inputStr.getBytes()));
|
||||
assertEquals(5, res.getRc());
|
||||
assertEquals(inputStr, new String(res.getStdout().toByteArray()));
|
||||
assertEquals("3,a,b,c,,," + LF,
|
||||
new String(res.getStderr().toByteArray()));
|
||||
}
|
||||
|
||||
private File writeTempFile(String body) throws IOException {
|
||||
File f = File.createTempFile("RunProcessTestScript_", "");
|
||||
JGitTestUtil.write(f, body);
|
||||
|
|
|
@ -1,5 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<component id="org.eclipse.jgit" version="2">
|
||||
<resource path="src/org/eclipse/jgit/attributes/AttributesNode.java" type="org.eclipse.jgit.attributes.AttributesNode">
|
||||
<filter comment="attributes weren't really usable in earlier versions" id="338792546">
|
||||
<message_arguments>
|
||||
<message_argument value="org.eclipse.jgit.attributes.AttributesNode"/>
|
||||
<message_argument value="getAttributes(String, boolean, Map<String,Attribute>)"/>
|
||||
</message_arguments>
|
||||
</filter>
|
||||
</resource>
|
||||
<resource path="src/org/eclipse/jgit/lib/BitmapIndex.java" type="org.eclipse.jgit.lib.BitmapIndex$BitmapBuilder">
|
||||
<filter comment="interface is implemented by extenders but not clients of the API" id="403804204">
|
||||
<message_arguments>
|
||||
|
@ -14,6 +22,14 @@
|
|||
</message_arguments>
|
||||
</filter>
|
||||
</resource>
|
||||
<resource path="src/org/eclipse/jgit/lib/Repository.java" type="org.eclipse.jgit.lib.Repository">
|
||||
<filter comment="Only implementors of Repository are affected. That should be allowed" id="336695337">
|
||||
<message_arguments>
|
||||
<message_argument value="org.eclipse.jgit.lib.Repository"/>
|
||||
<message_argument value="createAttributesNodeProvider()"/>
|
||||
</message_arguments>
|
||||
</filter>
|
||||
</resource>
|
||||
<resource path="src/org/eclipse/jgit/transport/PushCertificate.java" type="org.eclipse.jgit.transport.PushCertificate">
|
||||
<filter comment="PushCertificate wasn't really usable in 4.0" id="338722907">
|
||||
<message_arguments>
|
||||
|
@ -35,6 +51,20 @@
|
|||
</message_arguments>
|
||||
</filter>
|
||||
</resource>
|
||||
<resource path="src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java" type="org.eclipse.jgit.treewalk.WorkingTreeIterator">
|
||||
<filter comment="attributes weren't really usable in earlier versions" id="338792546">
|
||||
<message_arguments>
|
||||
<message_argument value="org.eclipse.jgit.treewalk.WorkingTreeIterator"/>
|
||||
<message_argument value="getGlobalAttributesNode()"/>
|
||||
</message_arguments>
|
||||
</filter>
|
||||
<filter comment="attributes weren't really usable in earlier versions" id="338792546">
|
||||
<message_arguments>
|
||||
<message_argument value="org.eclipse.jgit.treewalk.WorkingTreeIterator"/>
|
||||
<message_argument value="getInfoAttributesNode()"/>
|
||||
</message_arguments>
|
||||
</filter>
|
||||
</resource>
|
||||
<resource path="src/org/eclipse/jgit/util/FileUtils.java" type="org.eclipse.jgit.util.FileUtils">
|
||||
<filter id="338792546">
|
||||
<message_arguments>
|
||||
|
|
|
@ -2,7 +2,7 @@ eclipse.preferences.version=1
|
|||
org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=enabled
|
||||
org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
|
||||
org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jgit.annotations.NonNull
|
||||
org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jgit.annotations.NonByDefault
|
||||
org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jgit.annotations.NonNullByDefault
|
||||
org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jgit.annotations.Nullable
|
||||
org.eclipse.jdt.core.compiler.annotation.nullanalysis=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
|
|
|
@ -6,7 +6,8 @@ Bundle-Version: 4.2.0.qualifier
|
|||
Bundle-Localization: plugin
|
||||
Bundle-Vendor: %provider_name
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Export-Package: org.eclipse.jgit.api;version="4.2.0";
|
||||
Export-Package: org.eclipse.jgit.annotations;version="4.2.0",
|
||||
org.eclipse.jgit.api;version="4.2.0";
|
||||
uses:="org.eclipse.jgit.revwalk,
|
||||
org.eclipse.jgit.treewalk.filter,
|
||||
org.eclipse.jgit.diff,
|
||||
|
@ -20,9 +21,7 @@ Export-Package: org.eclipse.jgit.api;version="4.2.0";
|
|||
org.eclipse.jgit.submodule,
|
||||
org.eclipse.jgit.transport,
|
||||
org.eclipse.jgit.merge",
|
||||
org.eclipse.jgit.api.errors;version="4.2.0";
|
||||
uses:="org.eclipse.jgit.lib,
|
||||
org.eclipse.jgit.errors",
|
||||
org.eclipse.jgit.api.errors;version="4.2.0";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.errors",
|
||||
org.eclipse.jgit.attributes;version="4.2.0",
|
||||
org.eclipse.jgit.blame;version="4.2.0";
|
||||
uses:="org.eclipse.jgit.lib,
|
||||
|
@ -47,8 +46,7 @@ Export-Package: org.eclipse.jgit.api;version="4.2.0";
|
|||
org.eclipse.jgit.internal.storage.pack,
|
||||
org.eclipse.jgit.transport,
|
||||
org.eclipse.jgit.dircache",
|
||||
org.eclipse.jgit.events;version="4.2.0";
|
||||
uses:="org.eclipse.jgit.lib",
|
||||
org.eclipse.jgit.events;version="4.2.0";uses:="org.eclipse.jgit.lib",
|
||||
org.eclipse.jgit.fnmatch;version="4.2.0",
|
||||
org.eclipse.jgit.gitrepo;version="4.2.0";
|
||||
uses:="org.eclipse.jgit.api,
|
||||
|
@ -57,14 +55,11 @@ Export-Package: org.eclipse.jgit.api;version="4.2.0";
|
|||
org.xml.sax.helpers,
|
||||
org.xml.sax",
|
||||
org.eclipse.jgit.gitrepo.internal;version="4.2.0";x-internal:=true,
|
||||
org.eclipse.jgit.hooks;version="4.2.0";
|
||||
uses:="org.eclipse.jgit.lib",
|
||||
org.eclipse.jgit.hooks;version="4.2.0";uses:="org.eclipse.jgit.lib",
|
||||
org.eclipse.jgit.ignore;version="4.2.0",
|
||||
org.eclipse.jgit.ignore.internal;version="4.2.0";x-friends:="org.eclipse.jgit.test",
|
||||
org.eclipse.jgit.internal;version="4.2.0";x-friends:="org.eclipse.jgit.test,org.eclipse.jgit.http.test",
|
||||
org.eclipse.jgit.internal.storage.dfs;version="4.2.0";
|
||||
x-friends:="org.eclipse.jgit.test,
|
||||
org.eclipse.jgit.http.server",
|
||||
org.eclipse.jgit.internal.storage.dfs;version="4.2.0";x-friends:="org.eclipse.jgit.test,org.eclipse.jgit.http.server",
|
||||
org.eclipse.jgit.internal.storage.file;version="4.2.0";
|
||||
x-friends:="org.eclipse.jgit.test,
|
||||
org.eclipse.jgit.junit,
|
||||
|
@ -96,31 +91,18 @@ Export-Package: org.eclipse.jgit.api;version="4.2.0";
|
|||
org.eclipse.jgit.treewalk,
|
||||
org.eclipse.jgit.revwalk,
|
||||
org.eclipse.jgit.merge",
|
||||
org.eclipse.jgit.patch;version="4.2.0";
|
||||
uses:="org.eclipse.jgit.lib,
|
||||
org.eclipse.jgit.diff",
|
||||
org.eclipse.jgit.revplot;version="4.2.0";
|
||||
uses:="org.eclipse.jgit.lib,
|
||||
org.eclipse.jgit.revwalk",
|
||||
org.eclipse.jgit.patch;version="4.2.0";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.diff",
|
||||
org.eclipse.jgit.revplot;version="4.2.0";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.revwalk",
|
||||
org.eclipse.jgit.revwalk;version="4.2.0";
|
||||
uses:="org.eclipse.jgit.lib,
|
||||
org.eclipse.jgit.treewalk,
|
||||
org.eclipse.jgit.treewalk.filter,
|
||||
org.eclipse.jgit.diff,
|
||||
org.eclipse.jgit.revwalk.filter",
|
||||
org.eclipse.jgit.revwalk.filter;version="4.2.0";
|
||||
uses:="org.eclipse.jgit.revwalk,
|
||||
org.eclipse.jgit.lib,
|
||||
org.eclipse.jgit.util",
|
||||
org.eclipse.jgit.storage.file;version="4.2.0";
|
||||
uses:="org.eclipse.jgit.lib,
|
||||
org.eclipse.jgit.util",
|
||||
org.eclipse.jgit.storage.pack;version="4.2.0";
|
||||
uses:="org.eclipse.jgit.lib",
|
||||
org.eclipse.jgit.submodule;version="4.2.0";
|
||||
uses:="org.eclipse.jgit.lib,
|
||||
org.eclipse.jgit.treewalk.filter,
|
||||
org.eclipse.jgit.treewalk",
|
||||
org.eclipse.jgit.revwalk.filter;version="4.2.0";uses:="org.eclipse.jgit.revwalk,org.eclipse.jgit.lib,org.eclipse.jgit.util",
|
||||
org.eclipse.jgit.storage.file;version="4.2.0";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.util",
|
||||
org.eclipse.jgit.storage.pack;version="4.2.0";uses:="org.eclipse.jgit.lib",
|
||||
org.eclipse.jgit.submodule;version="4.2.0";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.treewalk.filter,org.eclipse.jgit.treewalk",
|
||||
org.eclipse.jgit.transport;version="4.2.0";
|
||||
uses:="org.eclipse.jgit.transport.resolver,
|
||||
org.eclipse.jgit.revwalk,
|
||||
|
@ -133,11 +115,8 @@ Export-Package: org.eclipse.jgit.api;version="4.2.0";
|
|||
org.eclipse.jgit.transport.http,
|
||||
org.eclipse.jgit.errors,
|
||||
org.eclipse.jgit.storage.pack",
|
||||
org.eclipse.jgit.transport.http;version="4.2.0";
|
||||
uses:="javax.net.ssl",
|
||||
org.eclipse.jgit.transport.resolver;version="4.2.0";
|
||||
uses:="org.eclipse.jgit.lib,
|
||||
org.eclipse.jgit.transport",
|
||||
org.eclipse.jgit.transport.http;version="4.2.0";uses:="javax.net.ssl",
|
||||
org.eclipse.jgit.transport.resolver;version="4.2.0";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.transport",
|
||||
org.eclipse.jgit.treewalk;version="4.2.0";
|
||||
uses:="org.eclipse.jgit.lib,
|
||||
org.eclipse.jgit.revwalk,
|
||||
|
@ -145,8 +124,7 @@ Export-Package: org.eclipse.jgit.api;version="4.2.0";
|
|||
org.eclipse.jgit.treewalk.filter,
|
||||
org.eclipse.jgit.util,
|
||||
org.eclipse.jgit.dircache",
|
||||
org.eclipse.jgit.treewalk.filter;version="4.2.0";
|
||||
uses:="org.eclipse.jgit.treewalk",
|
||||
org.eclipse.jgit.treewalk.filter;version="4.2.0";uses:="org.eclipse.jgit.treewalk",
|
||||
org.eclipse.jgit.util;version="4.2.0";
|
||||
uses:="org.eclipse.jgit.lib,
|
||||
org.eclipse.jgit.transport.http,
|
||||
|
|
|
@ -20,6 +20,7 @@ argumentIsNotAValidCommentString=Invalid comment: {0}
|
|||
atLeastOnePathIsRequired=At least one path is required.
|
||||
atLeastOnePatternIsRequired=At least one pattern is required.
|
||||
atLeastTwoFiltersNeeded=At least two filters needed.
|
||||
atomicPushNotSupported=Atomic push not supported.
|
||||
authenticationNotSupported=authentication not supported
|
||||
badBase64InputCharacterAt=Bad Base64 input character at {0} : {1} (decimal)
|
||||
badEntryDelimiter=Bad entry delimiter
|
||||
|
@ -45,6 +46,7 @@ cannotBeCombined=Cannot be combined.
|
|||
cannotBeRecursiveWhenTreesAreIncluded=TreeWalk shouldn't be recursive when tree objects are included.
|
||||
cannotChangeActionOnComment=Cannot change action on comment line in git-rebase-todo file, old action: {0}, new action: {1}.
|
||||
cannotChangeToComment=Cannot change a non-comment line to a comment line.
|
||||
cannotCheckoutFromUnbornBranch=Cannot checkout from unborn branch
|
||||
cannotCheckoutOursSwitchBranch=Checking out ours/theirs is only possible when checking out index, not when switching branches.
|
||||
cannotCombineSquashWithNoff=Cannot combine --squash with --no-ff.
|
||||
cannotCombineTreeFilterWithRevFilter=Cannot combine TreeFilter {0} with RevFilter {1}.
|
||||
|
@ -87,6 +89,7 @@ cannotReadBlob=Cannot read blob {0}
|
|||
cannotReadCommit=Cannot read commit {0}
|
||||
cannotReadFile=Cannot read file {0}
|
||||
cannotReadHEAD=cannot read HEAD: {0} {1}
|
||||
cannotReadIndex=The index file {0} exists but cannot be read
|
||||
cannotReadObject=Cannot read object
|
||||
cannotReadObjectsPath=Cannot read {0}/{1}: {2}
|
||||
cannotReadTree=Cannot read tree {0}
|
||||
|
@ -279,6 +282,8 @@ fileCannotBeDeleted=File cannot be deleted: {0}
|
|||
fileIsTooBigForThisConvenienceMethod=File is too big for this convenience method ({0} bytes).
|
||||
fileIsTooLarge=File is too large: {0}
|
||||
fileModeNotSetForPath=FileMode not set for path {0}
|
||||
filterExecutionFailed=Execution of filter command ''{0}'' on file ''{1}'' failed
|
||||
filterExecutionFailedRc=Execution of filter command ''{0}'' on file ''{1}'' failed with return code ''{2}'', message on stderr: ''{3}''
|
||||
findingGarbage=Finding garbage
|
||||
flagIsDisposed={0} is disposed.
|
||||
flagNotFromThis={0} not from this.
|
||||
|
@ -344,6 +349,7 @@ invalidPathReservedOnWindows=Invalid path (''{0}'' is reserved on Windows): {1}
|
|||
invalidReflogRevision=Invalid reflog revision: {0}
|
||||
invalidRefName=Invalid ref name: {0}
|
||||
invalidRemote=Invalid remote: {0}
|
||||
invalidRepositoryStateNoHead=Invalid repository --- cannot read HEAD
|
||||
invalidShallowObject=invalid shallow object {0}, expected commit
|
||||
invalidStageForPath=Invalid stage {0} for path {1}
|
||||
invalidTagOption=Invalid tag option: {0}
|
||||
|
@ -450,6 +456,7 @@ packfileIsTruncated=Packfile {0} is truncated.
|
|||
packfileIsTruncatedNoParam=Packfile is truncated.
|
||||
packHandleIsStale=Pack file {0} handle is stale, removing it from pack list
|
||||
packHasUnresolvedDeltas=pack has unresolved deltas
|
||||
packInaccessible=Pack file {0} now inaccessible; removing it from pack list
|
||||
packingCancelledDuringObjectsWriting=Packing cancelled during objects writing
|
||||
packObjectCountMismatch=Pack object count mismatch: pack {0} index {1}: {2}
|
||||
packRefs=Pack refs
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright (C) 2015, Andrey Loskutov <loskutov@gmx.de>
|
||||
* 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.annotations;
|
||||
|
||||
import static java.lang.annotation.ElementType.FIELD;
|
||||
import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
|
||||
import static java.lang.annotation.ElementType.METHOD;
|
||||
import static java.lang.annotation.ElementType.PARAMETER;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* JGit's replacement for the {@code javax.annotation.Nonnull}.
|
||||
* <p>
|
||||
* Denotes that a local variable, parameter, field, method return value expected
|
||||
* to be non {@code null}.
|
||||
*
|
||||
* @since 4.2
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.CLASS)
|
||||
@Target({ FIELD, METHOD, PARAMETER, LOCAL_VARIABLE })
|
||||
public @interface NonNull {
|
||||
// marker annotation with no members
|
||||
}
|
|
@ -54,13 +54,46 @@
|
|||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* JGit's replacement for the {@code javax.annotations.Nullable}.
|
||||
* Marks types that can hold the value {@code null} at run time.
|
||||
* <p>
|
||||
* Denotes that a local variable, parameter, field, method return value can be
|
||||
* {@code null}.
|
||||
* Unlike {@code org.eclipse.jdt.annotation.Nullable}, this has run-time
|
||||
* retention, allowing the annotation to be recognized by
|
||||
* <a href="https://github.com/google/guice/wiki/UseNullable">Guice</a>. Unlike
|
||||
* {@code javax.annotation.Nullable}, this does not involve importing new classes
|
||||
* to a standard (Java EE) package, so it can be deployed in an OSGi container
|
||||
* without running into
|
||||
* <a href="http://wiki.osgi.org/wiki/Split_Packages">split-package</a>
|
||||
* <a href="https://gerrit-review.googlesource.com/50112">problems</a>.
|
||||
* <p>
|
||||
* You can use this annotation to qualify a type in a method signature or local
|
||||
* variable declaration. The entity whose type has this annotation is allowed to
|
||||
* hold the value {@code null} at run time. This allows annotation based null
|
||||
* analysis to infer that
|
||||
* <ul>
|
||||
* <li>Binding a {@code null} value to the entity is legal.
|
||||
* <li>Dereferencing the entity is unsafe and can trigger a
|
||||
* {@code NullPointerException}.
|
||||
* </ul>
|
||||
* <p>
|
||||
* To avoid a dependency on Java 8, this annotation does not use
|
||||
* {@link Target @Target} {@code TYPE_USE}. That may change when JGit starts
|
||||
* requiring Java 8.
|
||||
* <p>
|
||||
* <b>Warning:</b> Please do not use this annotation on arrays. Different
|
||||
* annotation processors treat {@code @Nullable Object[]} differently: some
|
||||
* treat it as an array of nullable objects, for consistency with versions of
|
||||
* {@code Nullable} defined with {@code @Target} {@code TYPE_USE}, while others
|
||||
* treat it as a nullable array of objects. JGit therefore avoids using this
|
||||
* annotation on arrays altogether.
|
||||
*
|
||||
* @see <a href=
|
||||
* "http://types.cs.washington.edu/checker-framework/current/checker-framework-manual.html#faq-array-syntax-meaning">
|
||||
* The checker-framework manual</a>
|
||||
*
|
||||
* @since 4.2
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.CLASS)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ FIELD, METHOD, PARAMETER, LOCAL_VARIABLE })
|
||||
public @interface Nullable {
|
||||
// marker annotation with no members
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import org.eclipse.jgit.api.errors.FilterFailedException;
|
||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||
import org.eclipse.jgit.api.errors.JGitInternalException;
|
||||
import org.eclipse.jgit.api.errors.NoFilepatternException;
|
||||
|
@ -63,6 +64,7 @@
|
|||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.treewalk.FileTreeIterator;
|
||||
import org.eclipse.jgit.treewalk.TreeWalk;
|
||||
import org.eclipse.jgit.treewalk.TreeWalk.OperationType;
|
||||
import org.eclipse.jgit.treewalk.WorkingTreeIterator;
|
||||
import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
|
||||
|
||||
|
@ -139,6 +141,7 @@ public DirCache call() throws GitAPIException, NoFilepatternException {
|
|||
|
||||
try (ObjectInserter inserter = repo.newObjectInserter();
|
||||
final TreeWalk tw = new TreeWalk(repo)) {
|
||||
tw.setOperationType(OperationType.CHECKIN_OP);
|
||||
dc = repo.lockDirCache();
|
||||
DirCacheIterator c;
|
||||
|
||||
|
@ -146,6 +149,7 @@ public DirCache call() throws GitAPIException, NoFilepatternException {
|
|||
tw.addTree(new DirCacheBuildIterator(builder));
|
||||
if (workingTreeIterator == null)
|
||||
workingTreeIterator = new FileTreeIterator(repo);
|
||||
workingTreeIterator.setDirCacheIterator(tw, 0);
|
||||
tw.addTree(workingTreeIterator);
|
||||
tw.setRecursive(true);
|
||||
if (!addAll)
|
||||
|
@ -208,6 +212,9 @@ else if (!(path.equals(lastAddedFile))) {
|
|||
builder.commit();
|
||||
setCallable(false);
|
||||
} catch (IOException e) {
|
||||
Throwable cause = e.getCause();
|
||||
if (cause != null && cause instanceof FilterFailedException)
|
||||
throw (FilterFailedException) cause;
|
||||
throw new JGitInternalException(
|
||||
JGitText.get().exceptionCaughtDuringExecutionOfAddCommand, e);
|
||||
} finally {
|
||||
|
|
|
@ -222,6 +222,12 @@ public Ref call() throws GitAPIException, RefAlreadyExistsException,
|
|||
}
|
||||
|
||||
Ref headRef = repo.getRef(Constants.HEAD);
|
||||
if (headRef == null) {
|
||||
// TODO Git CLI supports checkout from unborn branch, we should
|
||||
// also allow this
|
||||
throw new UnsupportedOperationException(
|
||||
JGitText.get().cannotCheckoutFromUnbornBranch);
|
||||
}
|
||||
String shortHeadRef = getShortBranchName(headRef);
|
||||
String refLogMessage = "checkout: moving from " + shortHeadRef; //$NON-NLS-1$
|
||||
ObjectId branch;
|
||||
|
|
|
@ -86,6 +86,7 @@
|
|||
import org.eclipse.jgit.treewalk.CanonicalTreeParser;
|
||||
import org.eclipse.jgit.treewalk.FileTreeIterator;
|
||||
import org.eclipse.jgit.treewalk.TreeWalk;
|
||||
import org.eclipse.jgit.treewalk.TreeWalk.OperationType;
|
||||
import org.eclipse.jgit.util.ChangeIdUtil;
|
||||
|
||||
/**
|
||||
|
@ -328,9 +329,12 @@ private DirCache createTemporaryIndex(ObjectId headId, DirCache index,
|
|||
boolean emptyCommit = true;
|
||||
|
||||
try (TreeWalk treeWalk = new TreeWalk(repo)) {
|
||||
treeWalk.setOperationType(OperationType.CHECKIN_OP);
|
||||
int dcIdx = treeWalk
|
||||
.addTree(new DirCacheBuildIterator(existingBuilder));
|
||||
int fIdx = treeWalk.addTree(new FileTreeIterator(repo));
|
||||
FileTreeIterator fti = new FileTreeIterator(repo);
|
||||
fti.setDirCacheIterator(treeWalk, 0);
|
||||
int fIdx = treeWalk.addTree(fti);
|
||||
int hIdx = -1;
|
||||
if (headId != null)
|
||||
hIdx = treeWalk.addTree(rw.parseTree(headId));
|
||||
|
|
|
@ -713,8 +713,48 @@ public DescribeCommand describe() {
|
|||
}
|
||||
|
||||
/**
|
||||
* @return the git repository this class is interacting with; see {@link
|
||||
* #close()} for notes on closing this repository.
|
||||
* Return a command used to list the available remotes.
|
||||
*
|
||||
* @return a {@link RemoteListCommand}
|
||||
* @since 4.2
|
||||
*/
|
||||
public RemoteListCommand remoteList() {
|
||||
return new RemoteListCommand(repo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a command used to add a new remote.
|
||||
*
|
||||
* @return a {@link RemoteAddCommand}
|
||||
* @since 4.2
|
||||
*/
|
||||
public RemoteAddCommand remoteAdd() {
|
||||
return new RemoteAddCommand(repo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a command used to remove an existing remote.
|
||||
*
|
||||
* @return a {@link RemoteRemoveCommand}
|
||||
* @since 4.2
|
||||
*/
|
||||
public RemoteRemoveCommand remoteRemove() {
|
||||
return new RemoteRemoveCommand(repo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a command used to change the URL of an existing remote.
|
||||
*
|
||||
* @return a {@link RemoteSetUrlCommand}
|
||||
* @since 4.2
|
||||
*/
|
||||
public RemoteSetUrlCommand remoteSetUrl() {
|
||||
return new RemoteSetUrlCommand(repo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the git repository this class is interacting with; see
|
||||
* {@link #close()} for notes on closing this repository.
|
||||
*/
|
||||
public Repository getRepository() {
|
||||
return repo;
|
||||
|
|
|
@ -89,9 +89,8 @@ public class PushCommand extends
|
|||
private String receivePack = RemoteConfig.DEFAULT_RECEIVE_PACK;
|
||||
|
||||
private boolean dryRun;
|
||||
|
||||
private boolean atomic;
|
||||
private boolean force;
|
||||
|
||||
private boolean thin = Transport.DEFAULT_PUSH_THIN;
|
||||
|
||||
private OutputStream out;
|
||||
|
@ -145,6 +144,7 @@ public Iterable<PushResult> call() throws GitAPIException,
|
|||
transports = Transport.openAll(repo, remote, Transport.Operation.PUSH);
|
||||
for (final Transport transport : transports) {
|
||||
transport.setPushThin(thin);
|
||||
transport.setPushAtomic(atomic);
|
||||
if (receivePack != null)
|
||||
transport.setOptionReceivePack(receivePack);
|
||||
transport.setDryRun(dryRun);
|
||||
|
@ -396,6 +396,29 @@ public PushCommand setThin(boolean thin) {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if all-or-nothing behavior is requested.
|
||||
* @since 4.2
|
||||
*/
|
||||
public boolean isAtomic() {
|
||||
return atomic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests atomic push (all references updated, or no updates).
|
||||
*
|
||||
* Default setting is false.
|
||||
*
|
||||
* @param atomic
|
||||
* @return {@code this}
|
||||
* @since 4.2
|
||||
*/
|
||||
public PushCommand setAtomic(boolean atomic) {
|
||||
checkCallable();
|
||||
this.atomic = atomic;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the force preference for push operation
|
||||
*/
|
||||
|
|
|
@ -668,12 +668,13 @@ private void writeCurrentCommit(RevCommit commit) throws IOException {
|
|||
}
|
||||
|
||||
private void writeRewrittenHashes() throws RevisionSyntaxException,
|
||||
IOException {
|
||||
IOException, RefNotFoundException {
|
||||
File currentCommitFile = rebaseState.getFile(CURRENT_COMMIT);
|
||||
if (!currentCommitFile.exists())
|
||||
return;
|
||||
|
||||
String head = repo.resolve(Constants.HEAD).getName();
|
||||
ObjectId headId = getHead().getObjectId();
|
||||
String head = headId.getName();
|
||||
String currentCommits = rebaseState.readFile(CURRENT_COMMIT);
|
||||
for (String current : currentCommits.split("\n")) //$NON-NLS-1$
|
||||
RebaseState
|
||||
|
@ -743,8 +744,8 @@ private RevCommit doSquashFixup(boolean isSquash, RevCommit commitToPick,
|
|||
|
||||
private void resetSoftToParent() throws IOException,
|
||||
GitAPIException, CheckoutConflictException {
|
||||
Ref orig_head = repo.getRef(Constants.ORIG_HEAD);
|
||||
ObjectId orig_headId = orig_head.getObjectId();
|
||||
Ref ref = repo.getRef(Constants.ORIG_HEAD);
|
||||
ObjectId orig_head = ref == null ? null : ref.getObjectId();
|
||||
try {
|
||||
// we have already commited the cherry-picked commit.
|
||||
// what we need is to have changes introduced by this
|
||||
|
@ -755,7 +756,7 @@ private void resetSoftToParent() throws IOException,
|
|||
} finally {
|
||||
// set ORIG_HEAD back to where we started because soft
|
||||
// reset moved it
|
||||
repo.writeOrigHead(orig_headId);
|
||||
repo.writeOrigHead(orig_head);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -980,6 +981,9 @@ private PersonIdent parseAuthor() throws IOException {
|
|||
try {
|
||||
raw = IO.readFully(authorScriptFile);
|
||||
} catch (FileNotFoundException notFound) {
|
||||
if (authorScriptFile.exists()) {
|
||||
throw notFound;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return parseAuthor(raw);
|
||||
|
|
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* Copyright (C) 2015, Kaloyan Raev <kaloyan.r@zend.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.api;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||
import org.eclipse.jgit.api.errors.JGitInternalException;
|
||||
import org.eclipse.jgit.lib.Constants;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.lib.StoredConfig;
|
||||
import org.eclipse.jgit.transport.RefSpec;
|
||||
import org.eclipse.jgit.transport.RemoteConfig;
|
||||
import org.eclipse.jgit.transport.URIish;
|
||||
|
||||
/**
|
||||
* Used to add a new remote.
|
||||
*
|
||||
* This class has setters for all supported options and arguments of this
|
||||
* command and a {@link #call()} method to finally execute the command.
|
||||
*
|
||||
* @see <a href=
|
||||
* "http://www.kernel.org/pub/software/scm/git/docs/git-remote.html" > Git
|
||||
* documentation about Remote</a>
|
||||
*
|
||||
* @since 4.2
|
||||
*/
|
||||
public class RemoteAddCommand extends GitCommand<RemoteConfig> {
|
||||
|
||||
private String name;
|
||||
|
||||
private URIish uri;
|
||||
|
||||
/**
|
||||
* @param repo
|
||||
*/
|
||||
protected RemoteAddCommand(Repository repo) {
|
||||
super(repo);
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of the remote to add.
|
||||
*
|
||||
* @param name
|
||||
* a remote name
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* The URL of the repository for the new remote.
|
||||
*
|
||||
* @param uri
|
||||
* an URL for the remote
|
||||
*/
|
||||
public void setUri(URIish uri) {
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the {@code remote add} command with all the options and
|
||||
* parameters collected by the setter methods of this class.
|
||||
*
|
||||
* @return the {@link RemoteConfig} object of the added remote
|
||||
*/
|
||||
@Override
|
||||
public RemoteConfig call() throws GitAPIException {
|
||||
checkCallable();
|
||||
|
||||
try {
|
||||
StoredConfig config = repo.getConfig();
|
||||
RemoteConfig remote = new RemoteConfig(config, name);
|
||||
|
||||
RefSpec refSpec = new RefSpec();
|
||||
refSpec = refSpec.setForceUpdate(true);
|
||||
refSpec = refSpec.setSourceDestination(Constants.R_HEADS + "*", //$NON-NLS-1$
|
||||
Constants.R_REMOTES + name + "/*"); //$NON-NLS-1$
|
||||
remote.addFetchRefSpec(refSpec);
|
||||
|
||||
remote.addURI(uri);
|
||||
|
||||
remote.update(config);
|
||||
config.save();
|
||||
return remote;
|
||||
} catch (IOException | URISyntaxException e) {
|
||||
throw new JGitInternalException(e.getMessage(), e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright (C) 2015, Kaloyan Raev <kaloyan.r@zend.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.api;
|
||||
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||
import org.eclipse.jgit.api.errors.JGitInternalException;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.transport.RemoteConfig;
|
||||
|
||||
/**
|
||||
* Used to obtain the list of remotes.
|
||||
*
|
||||
* This class has setters for all supported options and arguments of this
|
||||
* command and a {@link #call()} method to finally execute the command.
|
||||
*
|
||||
* @see <a href=
|
||||
* "http://www.kernel.org/pub/software/scm/git/docs/git-remote.html" > Git
|
||||
* documentation about Remote</a>
|
||||
*
|
||||
* @since 4.2
|
||||
*/
|
||||
public class RemoteListCommand extends GitCommand<List<RemoteConfig>> {
|
||||
|
||||
/**
|
||||
* @param repo
|
||||
*/
|
||||
protected RemoteListCommand(Repository repo) {
|
||||
super(repo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the {@code remote} command with all the options and parameters
|
||||
* collected by the setter methods of this class.
|
||||
*
|
||||
* @return a list of {@link RemoteConfig} objects.
|
||||
*/
|
||||
@Override
|
||||
public List<RemoteConfig> call() throws GitAPIException {
|
||||
checkCallable();
|
||||
|
||||
try {
|
||||
return RemoteConfig.getAllRemoteConfigs(repo.getConfig());
|
||||
} catch (URISyntaxException e) {
|
||||
throw new JGitInternalException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* Copyright (C) 2015, Kaloyan Raev <kaloyan.r@zend.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.api;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||
import org.eclipse.jgit.api.errors.JGitInternalException;
|
||||
import org.eclipse.jgit.lib.ConfigConstants;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.lib.StoredConfig;
|
||||
import org.eclipse.jgit.transport.RemoteConfig;
|
||||
|
||||
/**
|
||||
* Used to remove an existing remote.
|
||||
*
|
||||
* This class has setters for all supported options and arguments of this
|
||||
* command and a {@link #call()} method to finally execute the command.
|
||||
*
|
||||
* @see <a href=
|
||||
* "http://www.kernel.org/pub/software/scm/git/docs/git-remote.html" > Git
|
||||
* documentation about Remote</a>
|
||||
*
|
||||
* @since 4.2
|
||||
*/
|
||||
public class RemoteRemoveCommand extends GitCommand<RemoteConfig> {
|
||||
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* @param repo
|
||||
*/
|
||||
protected RemoteRemoveCommand(Repository repo) {
|
||||
super(repo);
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of the remote to remove.
|
||||
*
|
||||
* @param name
|
||||
* a remote name
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the {@code remote} command with all the options and parameters
|
||||
* collected by the setter methods of this class.
|
||||
*
|
||||
* @return the {@link RemoteConfig} object of the removed remote
|
||||
*/
|
||||
@Override
|
||||
public RemoteConfig call() throws GitAPIException {
|
||||
checkCallable();
|
||||
|
||||
try {
|
||||
StoredConfig config = repo.getConfig();
|
||||
RemoteConfig remote = new RemoteConfig(config, name);
|
||||
config.unsetSection(ConfigConstants.CONFIG_KEY_REMOTE, name);
|
||||
config.save();
|
||||
return remote;
|
||||
} catch (IOException | URISyntaxException e) {
|
||||
throw new JGitInternalException(e.getMessage(), e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
* Copyright (C) 2015, Kaloyan Raev <kaloyan.r@zend.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.api;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||
import org.eclipse.jgit.api.errors.JGitInternalException;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.lib.StoredConfig;
|
||||
import org.eclipse.jgit.transport.RemoteConfig;
|
||||
import org.eclipse.jgit.transport.URIish;
|
||||
|
||||
/**
|
||||
* Used to to change the URL of a remote.
|
||||
*
|
||||
* This class has setters for all supported options and arguments of this
|
||||
* command and a {@link #call()} method to finally execute the command.
|
||||
*
|
||||
* @see <a href=
|
||||
* "http://www.kernel.org/pub/software/scm/git/docs/git-remote.html" > Git
|
||||
* documentation about Remote</a>
|
||||
*
|
||||
* @since 4.2
|
||||
*/
|
||||
public class RemoteSetUrlCommand extends GitCommand<RemoteConfig> {
|
||||
|
||||
private String name;
|
||||
|
||||
private URIish uri;
|
||||
|
||||
private boolean push;
|
||||
|
||||
/**
|
||||
* @param repo
|
||||
*/
|
||||
protected RemoteSetUrlCommand(Repository repo) {
|
||||
super(repo);
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of the remote to change the URL for.
|
||||
*
|
||||
* @param name
|
||||
* a remote name
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* The new URL for the remote.
|
||||
*
|
||||
* @param uri
|
||||
* an URL for the remote
|
||||
*/
|
||||
public void setUri(URIish uri) {
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to change the push URL of the remote instead of the fetch URL.
|
||||
*
|
||||
* @param push
|
||||
* <code>true</code> to set the push url, <code>false</code> to
|
||||
* set the fetch url
|
||||
*/
|
||||
public void setPush(boolean push) {
|
||||
this.push = push;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the {@code remote} command with all the options and parameters
|
||||
* collected by the setter methods of this class.
|
||||
*
|
||||
* @return the {@link RemoteConfig} object of the modified remote
|
||||
*/
|
||||
@Override
|
||||
public RemoteConfig call() throws GitAPIException {
|
||||
checkCallable();
|
||||
|
||||
try {
|
||||
StoredConfig config = repo.getConfig();
|
||||
RemoteConfig remote = new RemoteConfig(config, name);
|
||||
if (push) {
|
||||
List<URIish> uris = remote.getPushURIs();
|
||||
if (uris.size() > 1) {
|
||||
throw new JGitInternalException(
|
||||
"remote.newtest.pushurl has multiple values"); //$NON-NLS-1$
|
||||
} else if (uris.size() == 1) {
|
||||
remote.removePushURI(uris.get(0));
|
||||
}
|
||||
remote.addPushURI(uri);
|
||||
} else {
|
||||
List<URIish> uris = remote.getURIs();
|
||||
if (uris.size() > 1) {
|
||||
throw new JGitInternalException(
|
||||
"remote.newtest.url has multiple values"); //$NON-NLS-1$
|
||||
} else if (uris.size() == 1) {
|
||||
remote.removeURI(uris.get(0));
|
||||
}
|
||||
remote.addURI(uri);
|
||||
}
|
||||
|
||||
remote.update(config);
|
||||
config.save();
|
||||
return remote;
|
||||
} catch (IOException | URISyntaxException e) {
|
||||
throw new JGitInternalException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -51,6 +51,7 @@
|
|||
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||
import org.eclipse.jgit.api.errors.InvalidRefNameException;
|
||||
import org.eclipse.jgit.api.errors.JGitInternalException;
|
||||
import org.eclipse.jgit.api.errors.NoHeadException;
|
||||
import org.eclipse.jgit.api.errors.RefAlreadyExistsException;
|
||||
import org.eclipse.jgit.api.errors.RefNotFoundException;
|
||||
import org.eclipse.jgit.internal.JGitText;
|
||||
|
@ -121,6 +122,10 @@ public Ref call() throws GitAPIException, RefNotFoundException, InvalidRefNameEx
|
|||
fullOldName = ref.getName();
|
||||
} else {
|
||||
fullOldName = repo.getFullBranch();
|
||||
if (fullOldName == null) {
|
||||
throw new NoHeadException(
|
||||
JGitText.get().invalidRepositoryStateNoHead);
|
||||
}
|
||||
if (ObjectId.isId(fullOldName))
|
||||
throw new DetachedHeadException();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* Copyright (C) 2015, Christian Halstrick <christian.halstrick@sap.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.api.errors;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
|
||||
import org.eclipse.jgit.internal.JGitText;
|
||||
|
||||
/**
|
||||
* Exception thrown when the execution of a filter command failed
|
||||
*
|
||||
* @since 4.2
|
||||
*/
|
||||
public class FilterFailedException extends GitAPIException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String filterCommand;
|
||||
|
||||
private String path;
|
||||
|
||||
private byte[] stdout;
|
||||
|
||||
private String stderr;
|
||||
|
||||
private int rc;
|
||||
|
||||
/**
|
||||
* Thrown if during execution of filter command an exception occurred
|
||||
*
|
||||
* @param cause
|
||||
* the exception
|
||||
* @param filterCommand
|
||||
* the command which failed
|
||||
* @param path
|
||||
* the path processed by the filter
|
||||
*/
|
||||
public FilterFailedException(Exception cause, String filterCommand,
|
||||
String path) {
|
||||
super(MessageFormat.format(JGitText.get().filterExecutionFailed,
|
||||
filterCommand, path), cause);
|
||||
this.filterCommand = filterCommand;
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Thrown if a filter command returns a non-zero return code
|
||||
*
|
||||
* @param rc
|
||||
* the return code
|
||||
* @param filterCommand
|
||||
* the command which failed
|
||||
* @param path
|
||||
* the path processed by the filter
|
||||
* @param stdout
|
||||
* the output the filter generated so far. This should be limited
|
||||
* to reasonable size.
|
||||
* @param stderr
|
||||
* the stderr output of the filter
|
||||
*/
|
||||
@SuppressWarnings("boxing")
|
||||
public FilterFailedException(int rc, String filterCommand, String path,
|
||||
byte[] stdout, String stderr) {
|
||||
super(MessageFormat.format(JGitText.get().filterExecutionFailedRc,
|
||||
filterCommand, path, rc, stderr));
|
||||
this.rc = rc;
|
||||
this.filterCommand = filterCommand;
|
||||
this.path = path;
|
||||
this.stdout = stdout;
|
||||
this.stderr = stderr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the filterCommand
|
||||
*/
|
||||
public String getFilterCommand() {
|
||||
return filterCommand;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the path of the file processed by the filter command
|
||||
*/
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the output generated by the filter command. Might be truncated to
|
||||
* limit memory consumption.
|
||||
*/
|
||||
public byte[] getOutput() {
|
||||
return stdout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the error output returned by the filter command
|
||||
*/
|
||||
public String getError() {
|
||||
return stderr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the return code returned by the filter command
|
||||
*/
|
||||
public int getReturnCode() {
|
||||
return rc;
|
||||
}
|
||||
|
||||
}
|
|
@ -50,8 +50,10 @@
|
|||
* <li>Set - represented by {@link State#SET}</li>
|
||||
* <li>Unset - represented by {@link State#UNSET}</li>
|
||||
* <li>Set to a value - represented by {@link State#CUSTOM}</li>
|
||||
* <li>Unspecified - <code>null</code> is used instead of an instance of this
|
||||
* class</li>
|
||||
* <li>Unspecified - used to revert an attribute . This is crucial in order to
|
||||
* mark an attribute as unspecified in the attributes map and thus preventing
|
||||
* following (with lower priority) nodes from setting the attribute to a value
|
||||
* at all</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*
|
||||
|
@ -61,6 +63,7 @@ public final class Attribute {
|
|||
|
||||
/**
|
||||
* The attribute value state
|
||||
* see also https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html
|
||||
*/
|
||||
public static enum State {
|
||||
/** the attribute is set */
|
||||
|
@ -69,6 +72,13 @@ public static enum State {
|
|||
/** the attribute is unset */
|
||||
UNSET,
|
||||
|
||||
/**
|
||||
* the attribute appears as if it would not be defined at all
|
||||
*
|
||||
* @since 4.2
|
||||
*/
|
||||
UNSPECIFIED,
|
||||
|
||||
/** the attribute is set to a custom value */
|
||||
CUSTOM
|
||||
}
|
||||
|
@ -176,6 +186,8 @@ public String toString() {
|
|||
return key;
|
||||
case UNSET:
|
||||
return "-" + key; //$NON-NLS-1$
|
||||
case UNSPECIFIED:
|
||||
return "!" + key; //$NON-NLS-1$
|
||||
case CUSTOM:
|
||||
default:
|
||||
return key + "=" + value; //$NON-NLS-1$
|
||||
|
|
|
@ -0,0 +1,202 @@
|
|||
/*
|
||||
* Copyright (C) 2015, Ivan Motsch <ivan.motsch@bsiag.com>
|
||||
*
|
||||
* 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.attributes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jgit.attributes.Attribute.State;
|
||||
|
||||
/**
|
||||
* Represents a set of attributes for a path
|
||||
* <p>
|
||||
*
|
||||
* @since 4.2
|
||||
*/
|
||||
public final class Attributes {
|
||||
private final Map<String, Attribute> map = new LinkedHashMap<>();
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
*
|
||||
* @param attributes
|
||||
*/
|
||||
public Attributes(Attribute... attributes) {
|
||||
if (attributes != null) {
|
||||
for (Attribute a : attributes) {
|
||||
put(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the set does not contain any attributes
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return map.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* @return the attribute or null
|
||||
*/
|
||||
public Attribute get(String key) {
|
||||
return map.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return all attributes
|
||||
*/
|
||||
public Collection<Attribute> getAll() {
|
||||
return new ArrayList<>(map.values());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param a
|
||||
*/
|
||||
public void put(Attribute a) {
|
||||
map.put(a.getKey(), a);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
*/
|
||||
public void remove(String key) {
|
||||
map.remove(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* @return true if the {@link Attributes} contains this key
|
||||
*/
|
||||
public boolean containsKey(String key) {
|
||||
return map.containsKey(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the state.
|
||||
*
|
||||
* @param key
|
||||
*
|
||||
* @return the state (never returns <code>null</code>)
|
||||
*/
|
||||
public Attribute.State getState(String key) {
|
||||
Attribute a = map.get(key);
|
||||
return a != null ? a.getState() : Attribute.State.UNSPECIFIED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* @return true if the key is {@link State#SET}, false in all other cases
|
||||
*/
|
||||
public boolean isSet(String key) {
|
||||
return (getState(key) == State.SET);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* @return true if the key is {@link State#UNSET}, false in all other cases
|
||||
*/
|
||||
public boolean isUnset(String key) {
|
||||
return (getState(key) == State.UNSET);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* @return true if the key is {@link State#UNSPECIFIED}, false in all other
|
||||
* cases
|
||||
*/
|
||||
public boolean isUnspecified(String key) {
|
||||
return (getState(key) == State.UNSPECIFIED);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* @return true if the key is {@link State#CUSTOM}, false in all other cases
|
||||
* see {@link #getValue(String)} for the value of the key
|
||||
*/
|
||||
public boolean isCustom(String key) {
|
||||
return (getState(key) == State.CUSTOM);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* @return the attribute value (may be <code>null</code>)
|
||||
*/
|
||||
public String getValue(String key) {
|
||||
Attribute a = map.get(key);
|
||||
return a != null ? a.getValue() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append(getClass().getSimpleName());
|
||||
buf.append("["); //$NON-NLS-1$
|
||||
buf.append(" "); //$NON-NLS-1$
|
||||
for (Attribute a : map.values()) {
|
||||
buf.append(a.toString());
|
||||
buf.append(" "); //$NON-NLS-1$
|
||||
}
|
||||
buf.append("]"); //$NON-NLS-1$
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return map.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (!(obj instanceof Attributes))
|
||||
return false;
|
||||
Attributes other = (Attributes) obj;
|
||||
return this.map.equals(other.map);
|
||||
}
|
||||
|
||||
}
|
|
@ -50,7 +50,6 @@
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jgit.lib.Constants;
|
||||
|
||||
|
@ -134,11 +133,12 @@ public List<AttributesRule> getRules() {
|
|||
* true if the target item is a directory.
|
||||
* @param attributes
|
||||
* Map that will hold the attributes matching this entry path. If
|
||||
* it is not empty, this method will NOT override any
|
||||
* existing entry.
|
||||
* it is not empty, this method will NOT override any existing
|
||||
* entry.
|
||||
* @since 4.2
|
||||
*/
|
||||
public void getAttributes(String entryPath, boolean isDirectory,
|
||||
Map<String, Attribute> attributes) {
|
||||
public void getAttributes(String entryPath,
|
||||
boolean isDirectory, Attributes attributes) {
|
||||
// Parse rules in the reverse order that they were read since the last
|
||||
// entry should be used
|
||||
ListIterator<AttributesRule> ruleIterator = rules.listIterator(rules
|
||||
|
@ -153,7 +153,7 @@ public void getAttributes(String entryPath, boolean isDirectory,
|
|||
while (attributeIte.hasPrevious()) {
|
||||
Attribute attr = attributeIte.previous();
|
||||
if (!attributes.containsKey(attr.getKey()))
|
||||
attributes.put(attr.getKey(), attr);
|
||||
attributes.put(attr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright (C) 2014, Arthur Daussy <arthur.daussy@obeo.fr>
|
||||
* 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.attributes;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.jgit.lib.CoreConfig;
|
||||
|
||||
/**
|
||||
* An interface used to retrieve the global and info {@link AttributesNode}s.
|
||||
*
|
||||
* @since 4.2
|
||||
*
|
||||
*/
|
||||
public interface AttributesNodeProvider {
|
||||
|
||||
/**
|
||||
* Retrieve the {@link AttributesNode} that holds the information located
|
||||
* in $GIT_DIR/info/attributes file.
|
||||
*
|
||||
* @return the {@link AttributesNode} that holds the information located in
|
||||
* $GIT_DIR/info/attributes file.
|
||||
* @throws IOException
|
||||
* if an error is raised while parsing the attributes file
|
||||
*/
|
||||
public AttributesNode getInfoAttributesNode() throws IOException;
|
||||
|
||||
/**
|
||||
* Retrieve the {@link AttributesNode} that holds the information located
|
||||
* in the global gitattributes file.
|
||||
*
|
||||
* @return the {@link AttributesNode} that holds the information located in
|
||||
* the global gitattributes file.
|
||||
* @throws IOException
|
||||
* IOException if an error is raised while parsing the
|
||||
* attributes file
|
||||
* @see CoreConfig#getAttributesFile()
|
||||
*/
|
||||
public AttributesNode getGlobalAttributesNode() throws IOException;
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (C) 2015, Christian Halstrick <christian.halstrick@sap.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.attributes;
|
||||
|
||||
/**
|
||||
* Interface for classes which provide git attributes
|
||||
*
|
||||
* @since 4.2
|
||||
*/
|
||||
public interface AttributesProvider {
|
||||
/**
|
||||
* @return the currently active attributes
|
||||
*/
|
||||
public Attributes getAttributes();
|
||||
}
|
|
@ -84,6 +84,13 @@ private static List<Attribute> parseAttributes(String attributesLine) {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (attribute.startsWith("!")) {//$NON-NLS-1$
|
||||
if (attribute.length() > 1)
|
||||
result.add(new Attribute(attribute.substring(1),
|
||||
State.UNSPECIFIED));
|
||||
continue;
|
||||
}
|
||||
|
||||
final int equalsIndex = attribute.indexOf("="); //$NON-NLS-1$
|
||||
if (equalsIndex == -1)
|
||||
result.add(new Attribute(attribute, State.SET));
|
||||
|
@ -200,4 +207,16 @@ public boolean isMatch(String relativeTarget, boolean isDirectory) {
|
|||
boolean match = matcher.matches(relativeTarget, isDirectory);
|
||||
return match;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(pattern);
|
||||
for (Attribute a : attributes) {
|
||||
sb.append(" "); //$NON-NLS-1$
|
||||
sb.append(a);
|
||||
}
|
||||
return sb.toString();
|
||||
|
||||
}
|
||||
}
|
|
@ -132,7 +132,11 @@ private static class ObjectReaderSource extends ContentSource {
|
|||
|
||||
@Override
|
||||
public long size(String path, ObjectId id) throws IOException {
|
||||
return reader.getObjectSize(id, Constants.OBJ_BLOB);
|
||||
try {
|
||||
return reader.getObjectSize(id, Constants.OBJ_BLOB);
|
||||
} catch (MissingObjectException ignore) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -63,6 +63,7 @@
|
|||
import java.util.List;
|
||||
|
||||
import org.eclipse.jgit.errors.CorruptObjectException;
|
||||
import org.eclipse.jgit.errors.IndexReadException;
|
||||
import org.eclipse.jgit.errors.LockFailedException;
|
||||
import org.eclipse.jgit.errors.UnmergedPathException;
|
||||
import org.eclipse.jgit.events.IndexChangedEvent;
|
||||
|
@ -70,12 +71,15 @@
|
|||
import org.eclipse.jgit.internal.JGitText;
|
||||
import org.eclipse.jgit.internal.storage.file.FileSnapshot;
|
||||
import org.eclipse.jgit.internal.storage.file.LockFile;
|
||||
import org.eclipse.jgit.lib.AnyObjectId;
|
||||
import org.eclipse.jgit.lib.Constants;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.eclipse.jgit.lib.ObjectInserter;
|
||||
import org.eclipse.jgit.lib.ObjectReader;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.treewalk.FileTreeIterator;
|
||||
import org.eclipse.jgit.treewalk.TreeWalk;
|
||||
import org.eclipse.jgit.treewalk.TreeWalk.OperationType;
|
||||
import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
|
||||
import org.eclipse.jgit.util.FS;
|
||||
import org.eclipse.jgit.util.IO;
|
||||
|
@ -144,6 +148,28 @@ public static DirCache newInCore() {
|
|||
return new DirCache(null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new in memory index read from the contents of a tree.
|
||||
*
|
||||
* @param reader
|
||||
* reader to access the tree objects from a repository.
|
||||
* @param treeId
|
||||
* tree to read. Must identify a tree, not a tree-ish.
|
||||
* @return a new cache which has no backing store file, but contains the
|
||||
* contents of {@code treeId}.
|
||||
* @throws IOException
|
||||
* one or more trees not available from the ObjectReader.
|
||||
* @since 4.2
|
||||
*/
|
||||
public static DirCache read(ObjectReader reader, AnyObjectId treeId)
|
||||
throws IOException {
|
||||
DirCache d = newInCore();
|
||||
DirCacheBuilder b = d.builder();
|
||||
b.addTree(null, DirCacheEntry.STAGE_0, reader, treeId);
|
||||
b.finish();
|
||||
return d;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new in-core index representation and read an index from disk.
|
||||
* <p>
|
||||
|
@ -417,6 +443,12 @@ else if (snapshot == null || snapshot.isModified(liveFile)) {
|
|||
}
|
||||
}
|
||||
} catch (FileNotFoundException fnfe) {
|
||||
if (liveFile.exists()) {
|
||||
// Panic: the index file exists but we can't read it
|
||||
throw new IndexReadException(
|
||||
MessageFormat.format(JGitText.get().cannotReadIndex,
|
||||
liveFile.getAbsolutePath(), fnfe));
|
||||
}
|
||||
// Someone must have deleted it between our exists test
|
||||
// and actually opening the path. That's fine, its empty.
|
||||
//
|
||||
|
@ -869,8 +901,8 @@ public DirCacheEntry getEntry(final String path) {
|
|||
*/
|
||||
public DirCacheEntry[] getEntriesWithin(String path) {
|
||||
if (path.length() == 0) {
|
||||
final DirCacheEntry[] r = new DirCacheEntry[sortedEntries.length];
|
||||
System.arraycopy(sortedEntries, 0, r, 0, sortedEntries.length);
|
||||
DirCacheEntry[] r = new DirCacheEntry[entryCnt];
|
||||
System.arraycopy(sortedEntries, 0, r, 0, entryCnt);
|
||||
return r;
|
||||
}
|
||||
if (!path.endsWith("/")) //$NON-NLS-1$
|
||||
|
@ -963,6 +995,7 @@ private void registerIndexChangedListener(IndexChangedListener listener) {
|
|||
private void updateSmudgedEntries() throws IOException {
|
||||
List<String> paths = new ArrayList<String>(128);
|
||||
try (TreeWalk walk = new TreeWalk(repository)) {
|
||||
walk.setOperationType(OperationType.CHECKIN_OP);
|
||||
for (int i = 0; i < entryCnt; i++)
|
||||
if (sortedEntries[i].isSmudged())
|
||||
paths.add(sortedEntries[i].getPathString());
|
||||
|
@ -974,6 +1007,7 @@ private void updateSmudgedEntries() throws IOException {
|
|||
FileTreeIterator fIter = new FileTreeIterator(repository);
|
||||
walk.addTree(iIter);
|
||||
walk.addTree(fIter);
|
||||
fIter.setDirCacheIterator(walk, 0);
|
||||
walk.setRecursive(true);
|
||||
while (walk.next()) {
|
||||
iIter = walk.getTree(0, DirCacheIterator.class);
|
||||
|
|
|
@ -44,6 +44,9 @@
|
|||
|
||||
package org.eclipse.jgit.dircache;
|
||||
|
||||
import static org.eclipse.jgit.lib.FileMode.TYPE_MASK;
|
||||
import static org.eclipse.jgit.lib.FileMode.TYPE_TREE;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Arrays;
|
||||
|
@ -51,9 +54,7 @@
|
|||
import org.eclipse.jgit.internal.JGitText;
|
||||
import org.eclipse.jgit.lib.AnyObjectId;
|
||||
import org.eclipse.jgit.lib.ObjectReader;
|
||||
import org.eclipse.jgit.treewalk.AbstractTreeIterator;
|
||||
import org.eclipse.jgit.treewalk.CanonicalTreeParser;
|
||||
import org.eclipse.jgit.treewalk.TreeWalk;
|
||||
|
||||
/**
|
||||
* Updates a {@link DirCache} by adding individual {@link DirCacheEntry}s.
|
||||
|
@ -102,8 +103,9 @@ protected DirCacheBuilder(final DirCache dc, final int ecnt) {
|
|||
*/
|
||||
public void add(final DirCacheEntry newEntry) {
|
||||
if (newEntry.getRawMode() == 0)
|
||||
throw new IllegalArgumentException(MessageFormat.format(JGitText.get().fileModeNotSetForPath
|
||||
, newEntry.getPathString()));
|
||||
throw new IllegalArgumentException(MessageFormat.format(
|
||||
JGitText.get().fileModeNotSetForPath,
|
||||
newEntry.getPathString()));
|
||||
beforeAdd(newEntry);
|
||||
fastAdd(newEntry);
|
||||
}
|
||||
|
@ -162,27 +164,56 @@ public void keep(final int pos, int cnt) {
|
|||
* @throws IOException
|
||||
* a tree cannot be read to iterate through its entries.
|
||||
*/
|
||||
public void addTree(final byte[] pathPrefix, final int stage,
|
||||
final ObjectReader reader, final AnyObjectId tree) throws IOException {
|
||||
final TreeWalk tw = new TreeWalk(reader);
|
||||
tw.addTree(new CanonicalTreeParser(pathPrefix, reader, tree
|
||||
.toObjectId()));
|
||||
tw.setRecursive(true);
|
||||
if (tw.next()) {
|
||||
final DirCacheEntry newEntry = toEntry(stage, tw);
|
||||
beforeAdd(newEntry);
|
||||
fastAdd(newEntry);
|
||||
while (tw.next())
|
||||
fastAdd(toEntry(stage, tw));
|
||||
public void addTree(byte[] pathPrefix, int stage, ObjectReader reader,
|
||||
AnyObjectId tree) throws IOException {
|
||||
CanonicalTreeParser p = createTreeParser(pathPrefix, reader, tree);
|
||||
while (!p.eof()) {
|
||||
if (isTree(p)) {
|
||||
p = enterTree(p, reader);
|
||||
continue;
|
||||
}
|
||||
|
||||
DirCacheEntry first = toEntry(stage, p);
|
||||
beforeAdd(first);
|
||||
fastAdd(first);
|
||||
p = p.next();
|
||||
break;
|
||||
}
|
||||
|
||||
// Rest of tree entries are correctly sorted; use fastAdd().
|
||||
while (!p.eof()) {
|
||||
if (isTree(p)) {
|
||||
p = enterTree(p, reader);
|
||||
} else {
|
||||
fastAdd(toEntry(stage, p));
|
||||
p = p.next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private DirCacheEntry toEntry(final int stage, final TreeWalk tw) {
|
||||
final DirCacheEntry e = new DirCacheEntry(tw.getRawPath(), stage);
|
||||
final AbstractTreeIterator i;
|
||||
private static CanonicalTreeParser createTreeParser(byte[] pathPrefix,
|
||||
ObjectReader reader, AnyObjectId tree) throws IOException {
|
||||
return new CanonicalTreeParser(pathPrefix, reader, tree);
|
||||
}
|
||||
|
||||
i = tw.getTree(0, AbstractTreeIterator.class);
|
||||
e.setFileMode(tw.getFileMode(0));
|
||||
private static boolean isTree(CanonicalTreeParser p) {
|
||||
return (p.getEntryRawMode() & TYPE_MASK) == TYPE_TREE;
|
||||
}
|
||||
|
||||
private static CanonicalTreeParser enterTree(CanonicalTreeParser p,
|
||||
ObjectReader reader) throws IOException {
|
||||
p = p.createSubtreeIterator(reader);
|
||||
return p.eof() ? p.next() : p;
|
||||
}
|
||||
|
||||
private static DirCacheEntry toEntry(int stage, CanonicalTreeParser i) {
|
||||
byte[] buf = i.getEntryPathBuffer();
|
||||
int len = i.getEntryPathLength();
|
||||
byte[] path = new byte[len];
|
||||
System.arraycopy(buf, 0, path, 0, len);
|
||||
|
||||
DirCacheEntry e = new DirCacheEntry(path, stage);
|
||||
e.setFileMode(i.getEntryRawMode());
|
||||
e.setObjectIdFromRaw(i.idBuffer(), i.idOffset());
|
||||
return e;
|
||||
}
|
||||
|
@ -242,9 +273,9 @@ private void resort() {
|
|||
sorted = true;
|
||||
}
|
||||
|
||||
private static IllegalStateException bad(final DirCacheEntry a,
|
||||
final String msg) {
|
||||
return new IllegalStateException(msg + ": " + a.getStage() + " " //$NON-NLS-1$ //$NON-NLS-2$
|
||||
+ a.getPathString());
|
||||
private static IllegalStateException bad(DirCacheEntry a, String msg) {
|
||||
return new IllegalStateException(String.format(
|
||||
"%s: %d %s", //$NON-NLS-1$
|
||||
msg, Integer.valueOf(a.getStage()), a.getPathString()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,15 +52,18 @@
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jgit.api.errors.FilterFailedException;
|
||||
import org.eclipse.jgit.errors.CheckoutConflictException;
|
||||
import org.eclipse.jgit.errors.CorruptObjectException;
|
||||
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
|
||||
import org.eclipse.jgit.errors.IndexWriteException;
|
||||
import org.eclipse.jgit.errors.MissingObjectException;
|
||||
import org.eclipse.jgit.internal.JGitText;
|
||||
import org.eclipse.jgit.lib.Constants;
|
||||
import org.eclipse.jgit.lib.CoreConfig.AutoCRLF;
|
||||
import org.eclipse.jgit.lib.CoreConfig.SymLinks;
|
||||
import org.eclipse.jgit.lib.FileMode;
|
||||
import org.eclipse.jgit.lib.NullProgressMonitor;
|
||||
import org.eclipse.jgit.lib.ObjectChecker;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.eclipse.jgit.lib.ObjectLoader;
|
||||
|
@ -76,6 +79,7 @@
|
|||
import org.eclipse.jgit.treewalk.WorkingTreeOptions;
|
||||
import org.eclipse.jgit.treewalk.filter.PathFilter;
|
||||
import org.eclipse.jgit.util.FS;
|
||||
import org.eclipse.jgit.util.FS.ExecutionResult;
|
||||
import org.eclipse.jgit.util.FileUtils;
|
||||
import org.eclipse.jgit.util.RawParseUtils;
|
||||
import org.eclipse.jgit.util.SystemReader;
|
||||
|
@ -85,9 +89,10 @@
|
|||
* This class handles checking out one or two trees merging with the index.
|
||||
*/
|
||||
public class DirCacheCheckout {
|
||||
private static final int MAX_EXCEPTION_TEXT_SIZE = 10 * 1024;
|
||||
private Repository repo;
|
||||
|
||||
private HashMap<String, ObjectId> updated = new HashMap<String, ObjectId>();
|
||||
private HashMap<String, String> updated = new HashMap<String, String>();
|
||||
|
||||
private ArrayList<String> conflicts = new ArrayList<String>();
|
||||
|
||||
|
@ -112,9 +117,9 @@ public class DirCacheCheckout {
|
|||
private boolean emptyDirCache;
|
||||
|
||||
/**
|
||||
* @return a list of updated paths and objectIds
|
||||
* @return a list of updated paths and smudgeFilterCommands
|
||||
*/
|
||||
public Map<String, ObjectId> getUpdated() {
|
||||
public Map<String, String> getUpdated() {
|
||||
return updated;
|
||||
}
|
||||
|
||||
|
@ -447,7 +452,8 @@ private boolean doCheckout() throws CorruptObjectException, IOException,
|
|||
for (String path : updated.keySet()) {
|
||||
DirCacheEntry entry = dc.getEntry(path);
|
||||
if (!FileMode.GITLINK.equals(entry.getRawMode()))
|
||||
checkoutEntry(repo, entry, objectReader, false);
|
||||
checkoutEntry(repo, entry, objectReader, false,
|
||||
updated.get(path));
|
||||
}
|
||||
|
||||
// commit the index builder - a new index is persisted
|
||||
|
@ -996,9 +1002,12 @@ private void remove(String path) {
|
|||
removed.add(path);
|
||||
}
|
||||
|
||||
private void update(String path, ObjectId mId, FileMode mode) {
|
||||
private void update(String path, ObjectId mId, FileMode mode)
|
||||
throws IOException {
|
||||
if (!FileMode.TREE.equals(mode)) {
|
||||
updated.put(path, mId);
|
||||
updated.put(path,
|
||||
walk.getFilterCommand(Constants.ATTR_FILTER_TYPE_SMUDGE));
|
||||
|
||||
DirCacheEntry entry = new DirCacheEntry(path, DirCacheEntry.STAGE_0);
|
||||
entry.setObjectId(mId);
|
||||
entry.setFileMode(mode);
|
||||
|
@ -1150,7 +1159,7 @@ private boolean isModifiedSubtree_IndexTree(String path, ObjectId tree)
|
|||
*/
|
||||
public static void checkoutEntry(Repository repo, DirCacheEntry entry,
|
||||
ObjectReader or) throws IOException {
|
||||
checkoutEntry(repo, entry, or, false);
|
||||
checkoutEntry(repo, entry, or, false, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1186,6 +1195,46 @@ public static void checkoutEntry(Repository repo, DirCacheEntry entry,
|
|||
*/
|
||||
public static void checkoutEntry(Repository repo, DirCacheEntry entry,
|
||||
ObjectReader or, boolean deleteRecursive) throws IOException {
|
||||
checkoutEntry(repo, entry, or, deleteRecursive, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the file in the working tree with content and mode from an entry
|
||||
* in the index. The new content is first written to a new temporary file in
|
||||
* the same directory as the real file. Then that new file is renamed to the
|
||||
* final filename.
|
||||
*
|
||||
* <p>
|
||||
* <b>Note:</b> if the entry path on local file system exists as a file, it
|
||||
* will be deleted and if it exists as a directory, it will be deleted
|
||||
* recursively, independently if has any content.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* TODO: this method works directly on File IO, we may need another
|
||||
* abstraction (like WorkingTreeIterator). This way we could tell e.g.
|
||||
* Eclipse that Files in the workspace got changed
|
||||
* </p>
|
||||
*
|
||||
* @param repo
|
||||
* repository managing the destination work tree.
|
||||
* @param entry
|
||||
* the entry containing new mode and content
|
||||
* @param or
|
||||
* object reader to use for checkout
|
||||
* @param deleteRecursive
|
||||
* true to recursively delete final path if it exists on the file
|
||||
* system
|
||||
* @param smudgeFilterCommand
|
||||
* the filter command to be run for smudging the entry to be
|
||||
* checked out
|
||||
*
|
||||
* @throws IOException
|
||||
* @since 4.2
|
||||
*/
|
||||
public static void checkoutEntry(Repository repo, DirCacheEntry entry,
|
||||
ObjectReader or, boolean deleteRecursive,
|
||||
String smudgeFilterCommand) throws IOException {
|
||||
ObjectLoader ol = or.open(entry.getObjectId());
|
||||
File f = new File(repo.getWorkTree(), entry.getPathString());
|
||||
File parentDir = f.getParentFile();
|
||||
|
@ -1210,14 +1259,52 @@ public static void checkoutEntry(Repository repo, DirCacheEntry entry,
|
|||
OutputStream channel = new FileOutputStream(tmpFile);
|
||||
if (opt.getAutoCRLF() == AutoCRLF.TRUE)
|
||||
channel = new AutoCRLFOutputStream(channel);
|
||||
try {
|
||||
ol.copyTo(channel);
|
||||
} finally {
|
||||
channel.close();
|
||||
if (smudgeFilterCommand != null) {
|
||||
ProcessBuilder filterProcessBuilder = fs
|
||||
.runInShell(smudgeFilterCommand, new String[0]);
|
||||
filterProcessBuilder.directory(repo.getWorkTree());
|
||||
filterProcessBuilder.environment().put(Constants.GIT_DIR_KEY,
|
||||
repo.getDirectory().getAbsolutePath());
|
||||
ExecutionResult result;
|
||||
int rc;
|
||||
try {
|
||||
// TODO: wire correctly with AUTOCRLF
|
||||
result = fs.execute(filterProcessBuilder, ol.openStream());
|
||||
rc = result.getRc();
|
||||
if (rc == 0) {
|
||||
result.getStdout().writeTo(channel,
|
||||
NullProgressMonitor.INSTANCE);
|
||||
}
|
||||
} catch (IOException | InterruptedException e) {
|
||||
throw new IOException(new FilterFailedException(e,
|
||||
smudgeFilterCommand, entry.getPathString()));
|
||||
|
||||
} finally {
|
||||
channel.close();
|
||||
}
|
||||
if (rc != 0) {
|
||||
throw new IOException(new FilterFailedException(rc,
|
||||
smudgeFilterCommand, entry.getPathString(),
|
||||
result.getStdout().toByteArray(MAX_EXCEPTION_TEXT_SIZE),
|
||||
RawParseUtils.decode(result.getStderr()
|
||||
.toByteArray(MAX_EXCEPTION_TEXT_SIZE))));
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
ol.copyTo(channel);
|
||||
} finally {
|
||||
channel.close();
|
||||
}
|
||||
}
|
||||
// The entry needs to correspond to the on-disk filesize. If the content
|
||||
// was filtered (either by autocrlf handling or smudge filters) ask the
|
||||
// filesystem again for the length. Otherwise the objectloader knows the
|
||||
// size
|
||||
if (opt.getAutoCRLF() == AutoCRLF.TRUE || smudgeFilterCommand != null) {
|
||||
entry.setLength(tmpFile.length());
|
||||
} else {
|
||||
entry.setLength(ol.getSize());
|
||||
}
|
||||
entry.setLength(opt.getAutoCRLF() == AutoCRLF.TRUE ? //
|
||||
tmpFile.length() // AutoCRLF wants on-disk-size
|
||||
: (int) ol.getSize());
|
||||
|
||||
if (opt.isFileMode() && fs.supportsExecute()) {
|
||||
if (FileMode.EXECUTABLE_FILE.equals(entry.getRawMode())) {
|
||||
|
@ -1255,24 +1342,6 @@ private static void checkValidPath(CanonicalTreeParser t)
|
|||
checkValidPathSegment(chk, i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if path is a valid path for a checked out file name or ref name.
|
||||
*
|
||||
* @param path
|
||||
* @throws InvalidPathException
|
||||
* if the path is invalid
|
||||
* @since 3.3
|
||||
*/
|
||||
static void checkValidPath(String path) throws InvalidPathException {
|
||||
try {
|
||||
SystemReader.getInstance().checkPath(path);
|
||||
} catch (CorruptObjectException e) {
|
||||
InvalidPathException p = new InvalidPathException(path);
|
||||
p.initCause(e);
|
||||
throw p;
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkValidPathSegment(ObjectChecker chk,
|
||||
CanonicalTreeParser t) throws InvalidPathException {
|
||||
try {
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
import org.eclipse.jgit.util.IO;
|
||||
import org.eclipse.jgit.util.MutableInteger;
|
||||
import org.eclipse.jgit.util.NB;
|
||||
import org.eclipse.jgit.util.SystemReader;
|
||||
|
||||
/**
|
||||
* A single file (or stage of a file) in a {@link DirCache}.
|
||||
|
@ -191,7 +192,7 @@ public class DirCacheEntry {
|
|||
}
|
||||
|
||||
try {
|
||||
DirCacheCheckout.checkValidPath(toString(path));
|
||||
checkPath(path);
|
||||
} catch (InvalidPathException e) {
|
||||
CorruptObjectException p =
|
||||
new CorruptObjectException(e.getMessage());
|
||||
|
@ -263,7 +264,7 @@ public DirCacheEntry(final byte[] newPath) {
|
|||
/**
|
||||
* Create an empty entry at the specified stage.
|
||||
*
|
||||
* @param newPath
|
||||
* @param path
|
||||
* name of the cache entry, in the standard encoding.
|
||||
* @param stage
|
||||
* the stage index of the new entry.
|
||||
|
@ -274,16 +275,16 @@ public DirCacheEntry(final byte[] newPath) {
|
|||
* range 0..3, inclusive.
|
||||
*/
|
||||
@SuppressWarnings("boxing")
|
||||
public DirCacheEntry(final byte[] newPath, final int stage) {
|
||||
DirCacheCheckout.checkValidPath(toString(newPath));
|
||||
public DirCacheEntry(byte[] path, final int stage) {
|
||||
checkPath(path);
|
||||
if (stage < 0 || 3 < stage)
|
||||
throw new IllegalArgumentException(MessageFormat.format(
|
||||
JGitText.get().invalidStageForPath,
|
||||
stage, toString(newPath)));
|
||||
stage, toString(path)));
|
||||
|
||||
info = new byte[INFO_LEN];
|
||||
infoOffset = 0;
|
||||
path = newPath;
|
||||
this.path = path;
|
||||
|
||||
int flags = ((stage & 0x3) << 12);
|
||||
if (path.length < NAME_MASK)
|
||||
|
@ -498,12 +499,16 @@ public void setFileMode(final FileMode mode) {
|
|||
switch (mode.getBits() & FileMode.TYPE_MASK) {
|
||||
case FileMode.TYPE_MISSING:
|
||||
case FileMode.TYPE_TREE:
|
||||
throw new IllegalArgumentException(MessageFormat.format(JGitText.get().invalidModeForPath
|
||||
, mode, getPathString()));
|
||||
throw new IllegalArgumentException(MessageFormat.format(
|
||||
JGitText.get().invalidModeForPath, mode, getPathString()));
|
||||
}
|
||||
NB.encodeInt32(info, infoOffset + P_MODE, mode.getBits());
|
||||
}
|
||||
|
||||
void setFileMode(int mode) {
|
||||
NB.encodeInt32(info, infoOffset + P_MODE, mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cached creation time of this file, in milliseconds.
|
||||
*
|
||||
|
@ -730,6 +735,16 @@ private int getExtendedFlags() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
private static void checkPath(byte[] path) {
|
||||
try {
|
||||
SystemReader.getInstance().checkPath(path);
|
||||
} catch (CorruptObjectException e) {
|
||||
InvalidPathException p = new InvalidPathException(toString(path));
|
||||
p.initCause(e);
|
||||
throw p;
|
||||
}
|
||||
}
|
||||
|
||||
private static String toString(final byte[] path) {
|
||||
return Constants.CHARSET.decode(ByteBuffer.wrap(path)).toString();
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue