Merge branch 'master' into stable-4.2

Change-Id: Ia92c91e1226da7d6455ab14f1e255a1546f8f357
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
This commit is contained in:
Matthias Sohn 2015-12-15 00:07:22 +01:00
commit edec10dc39
147 changed files with 5996 additions and 778 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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();

View File

@ -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();

View File

@ -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),

View File

@ -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>();

View File

@ -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;

View File

@ -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

View File

@ -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());
}

View File

@ -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="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry id=&quot;org.eclipse.jdt.launching.classpathentry.defaultClasspath&quot;&gt;&#10;&lt;memento exportedEntriesOnly=&quot;false&quot; project=&quot;org.eclipse.jgit.pgm.test&quot;/&gt;&#10;&lt;/runtimeClasspathEntry&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry path=&quot;3&quot; projectName=&quot;org.eclipse.jgit.java7&quot; type=&quot;1&quot;/&gt;&#10;"/>
</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"/>

View File

@ -19,7 +19,6 @@
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry id=&quot;org.eclipse.jdt.launching.classpathentry.defaultClasspath&quot;&gt;&#10;&lt;memento exportedEntriesOnly=&quot;false&quot; project=&quot;org.eclipse.jgit.pgm.test&quot;/&gt;&#10;&lt;/runtimeClasspathEntry&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry path=&quot;3&quot; projectName=&quot;org.eclipse.jgit.java7&quot; type=&quot;1&quot;/&gt;&#10;"/>
</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"/>

View File

@ -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());
}

View File

@ -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"));
}
}

View File

@ -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

View File

@ -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();
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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();

View File

@ -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)) {

View File

@ -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) {

View File

@ -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);
}
}
}
}

View File

@ -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());
}
}
}
}

View File

@ -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());

View File

@ -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())

View File

@ -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$

View File

@ -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;

View File

@ -18,7 +18,6 @@
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry id=&quot;org.eclipse.jdt.launching.classpathentry.defaultClasspath&quot;&gt;&#10;&lt;memento exportedEntriesOnly=&quot;false&quot; project=&quot;org.eclipse.jgit.test&quot;/&gt;&#10;&lt;/runtimeClasspathEntry&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry path=&quot;3&quot; projectName=&quot;org.eclipse.jgit.java7&quot; type=&quot;1&quot;/&gt;&#10;"/>
</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"/>

View File

@ -19,7 +19,6 @@
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry id=&quot;org.eclipse.jdt.launching.classpathentry.defaultClasspath&quot;&gt;&#10;&lt;memento exportedEntriesOnly=&quot;false&quot; project=&quot;org.eclipse.jgit.test&quot;/&gt;&#10;&lt;/runtimeClasspathEntry&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry path=&quot;3&quot; projectName=&quot;org.eclipse.jgit.java7&quot; type=&quot;1&quot;/&gt;&#10;"/>
</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"/>

View File

@ -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());
}
}

View File

@ -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 {

View File

@ -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;
}
}

View File

@ -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());

View File

@ -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();

View File

@ -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

View File

@ -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)

View File

@ -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));
}
}

View File

@ -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());
}
}

View File

@ -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));
}
}

View File

@ -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));
}
}

View File

@ -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());

View File

@ -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());

View File

@ -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());

View File

@ -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(

View File

@ -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);
}
}

View File

@ -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(

View File

@ -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());
}
}

View File

@ -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");

View File

@ -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;

View File

@ -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());
}
}

View File

@ -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

View File

@ -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());

View File

@ -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)

View File

@ -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);

View File

@ -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();

View File

@ -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());

View File

@ -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);

View File

@ -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,

View File

@ -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 "

View File

@ -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;
}
}

View File

@ -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());
}
}

View File

@ -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());
}
}

View File

@ -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());
}
}

View File

@ -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";
}
}

View File

@ -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());
}
}

View File

@ -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()) {

View File

@ -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");

View File

@ -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, "å");

View File

@ -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");

View 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());
}
}

View File

@ -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);

View File

@ -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&lt;String,Attribute&gt;)"/>
</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>

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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
}

View File

@ -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

View File

@ -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 {

View File

@ -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;

View File

@ -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));

View File

@ -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;

View File

@ -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
*/

View File

@ -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);

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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();
}

View File

@ -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;
}
}

View File

@ -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$

View File

@ -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);
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}

View File

@ -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();
}

View File

@ -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();
}
}

View File

@ -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

View File

@ -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);

View File

@ -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()));
}
}

View File

@ -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 {

View File

@ -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