Merge branch 'stable-4.3'

* stable-4.3:
  Scan loose ref before packed in case gc about to remove the loose
  Fix possible NPEs when reporting transport errors
  Fix calling of clean/smudge filters from Checkout,MergeCommands
  Fix ApplyCommand when result of patch is an empty file

Change-Id: I0dc76b7a8c87ce8e0386a1b9e0fa92a3aa62abf7
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
This commit is contained in:
Matthias Sohn 2016-05-05 01:13:35 +02:00
commit 89db7e01fa
11 changed files with 59 additions and 34 deletions

View File

@ -146,6 +146,16 @@ public void testModifyE() throws Exception {
b.getString(0, b.size(), false)); b.getString(0, b.size(), false));
} }
@Test
public void testModifyW() throws Exception {
ApplyResult result = init("W");
assertEquals(1, result.getUpdatedFiles().size());
assertEquals(new File(db.getWorkTree(), "W"),
result.getUpdatedFiles().get(0));
checkFile(new File(db.getWorkTree(), "W"),
b.getString(0, b.size(), false));
}
@Test @Test
public void testModifyX() throws Exception { public void testModifyX() throws Exception {
ApplyResult result = init("X"); ApplyResult result = init("X");

View File

@ -88,7 +88,6 @@
import org.eclipse.jgit.transport.URIish; import org.eclipse.jgit.transport.URIish;
import org.eclipse.jgit.util.FileUtils; import org.eclipse.jgit.util.FileUtils;
import org.junit.Before; import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
public class CheckoutCommandTest extends RepositoryTestCase { public class CheckoutCommandTest extends RepositoryTestCase {
@ -740,11 +739,9 @@ public void testSmudgeFilter_deleteFileAndCreateBranchAndRestoreFromCommit()
} }
@Test @Test
@Ignore public void testSmudgeAndClean() throws Exception {
public void testSmudgeAndClean() throws IOException, GitAPIException { File clean_filter = writeTempFile("sed s/V1/@version/g");
// @TODO: fix this test File smudge_filter = writeTempFile("sed s/@version/V1/g");
File clean_filter = writeTempFile("sed s/V1/@version/g -");
File smudge_filter = writeTempFile("sed s/@version/V1/g -");
try (Git git2 = new Git(db)) { try (Git git2 = new Git(db)) {
StoredConfig config = git.getRepository().getConfig(); StoredConfig config = git.getRepository().getConfig();
@ -753,33 +750,39 @@ public void testSmudgeAndClean() throws IOException, GitAPIException {
config.setString("filter", "tstFilter", "clean", config.setString("filter", "tstFilter", "clean",
"sh " + slashify(clean_filter.getPath())); "sh " + slashify(clean_filter.getPath()));
config.save(); config.save();
writeTrashFile(".gitattributes", "*.txt filter=tstFilter"); writeTrashFile(".gitattributes", "filterTest.txt filter=tstFilter");
git2.add().addFilepattern(".gitattributes").call(); git2.add().addFilepattern(".gitattributes").call();
git2.commit().setMessage("add attributes").call(); git2.commit().setMessage("add attributes").call();
writeTrashFile("filterTest.txt", "hello world, V1"); fsTick(writeTrashFile("filterTest.txt", "hello world, V1\n"));
git2.add().addFilepattern("filterTest.txt").call(); git2.add().addFilepattern("filterTest.txt").call();
git2.commit().setMessage("add filterText.txt").call(); RevCommit one = git2.commit().setMessage("add filterText.txt").call();
assertEquals( assertEquals(
"[.gitattributes, mode:100644, content:*.txt filter=tstFilter][Test.txt, mode:100644, content:Some other change][filterTest.txt, mode:100644, content:hello world, @version]", "[.gitattributes, mode:100644, content:filterTest.txt filter=tstFilter][Test.txt, mode:100644, content:Some change][filterTest.txt, mode:100644, content:hello world, @version\n]",
indexState(CONTENT)); indexState(CONTENT));
git2.checkout().setCreateBranch(true).setName("test2").call(); fsTick(writeTrashFile("filterTest.txt", "bon giorno world, V1\n"));
writeTrashFile("filterTest.txt", "bon giorno world, V1");
git2.add().addFilepattern("filterTest.txt").call(); git2.add().addFilepattern("filterTest.txt").call();
git2.commit().setMessage("modified filterText.txt").call(); RevCommit two = git2.commit().setMessage("modified filterTest.txt").call();
assertTrue(git2.status().call().isClean()); assertTrue(git2.status().call().isClean());
assertEquals( 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]", "[.gitattributes, mode:100644, content:filterTest.txt filter=tstFilter][Test.txt, mode:100644, content:Some change][filterTest.txt, mode:100644, content:bon giorno world, @version\n]",
indexState(CONTENT)); indexState(CONTENT));
git2.checkout().setName("refs/heads/test").call(); git2.checkout().setName(one.getName()).call();
assertTrue(git2.status().call().isClean()); assertTrue(git2.status().call().isClean());
assertEquals( assertEquals(
"[.gitattributes, mode:100644, content:*.txt filter=tstFilter][Test.txt, mode:100644, content:Some other change][filterTest.txt, mode:100644, content:hello world, @version]", "[.gitattributes, mode:100644, content:filterTest.txt filter=tstFilter][Test.txt, mode:100644, content:Some change][filterTest.txt, mode:100644, content:hello world, @version\n]",
indexState(CONTENT)); indexState(CONTENT));
assertEquals("hello world, V1", read("filterTest.txt")); assertEquals("hello world, V1\n", read("filterTest.txt"));
git2.checkout().setName(two.getName()).call();
assertTrue(git2.status().call().isClean());
assertEquals(
"[.gitattributes, mode:100644, content:filterTest.txt filter=tstFilter][Test.txt, mode:100644, content:Some change][filterTest.txt, mode:100644, content:bon giorno world, @version\n]",
indexState(CONTENT));
assertEquals("bon giorno world, V1\n", read("filterTest.txt"));
} }
} }

View File

@ -223,12 +223,16 @@ private void apply(File f, FileHeader fh)
pos++; pos++;
break; break;
case '-': case '-':
if (!newLines.get(hh.getNewStartLine() - 1 + pos).equals( if (hh.getNewStartLine() == 0) {
hunkLine.substring(1))) { newLines.clear();
} else {
if (!newLines.get(hh.getNewStartLine() - 1 + pos)
.equals(hunkLine.substring(1))) {
throw new PatchApplyException(MessageFormat.format( throw new PatchApplyException(MessageFormat.format(
JGitText.get().patchApplyException, hh)); JGitText.get().patchApplyException, hh));
} }
newLines.remove(hh.getNewStartLine() - 1 + pos); newLines.remove(hh.getNewStartLine() - 1 + pos);
}
break; break;
case '+': case '+':
newLines.add(hh.getNewStartLine() - 1 + pos, newLines.add(hh.getNewStartLine() - 1 + pos,
@ -250,7 +254,9 @@ private void apply(File f, FileHeader fh)
// still there! // still there!
sb.append(l).append('\n'); sb.append(l).append('\n');
} }
if (sb.length() > 0) {
sb.deleteCharAt(sb.length() - 1); sb.deleteCharAt(sb.length() - 1);
}
FileWriter fw = new FileWriter(f); FileWriter fw = new FileWriter(f);
fw.write(sb.toString()); fw.write(sb.toString());
fw.close(); fw.close();

View File

@ -280,8 +280,9 @@ public void preScanTwoTrees() throws CorruptObjectException, IOException {
addTree(walk, headCommitTree); addTree(walk, headCommitTree);
addTree(walk, mergeCommitTree); addTree(walk, mergeCommitTree);
walk.addTree(new DirCacheBuildIterator(builder)); int dciPos = walk.addTree(new DirCacheBuildIterator(builder));
walk.addTree(workingTree); walk.addTree(workingTree);
workingTree.setDirCacheIterator(walk, dciPos);
while (walk.next()) { while (walk.next()) {
processEntry(walk.getTree(0, CanonicalTreeParser.class), processEntry(walk.getTree(0, CanonicalTreeParser.class),
@ -320,8 +321,9 @@ public void prescanOneTree()
walk = new NameConflictTreeWalk(repo); walk = new NameConflictTreeWalk(repo);
addTree(walk, mergeCommitTree); addTree(walk, mergeCommitTree);
walk.addTree(new DirCacheBuildIterator(builder)); int dciPos = walk.addTree(new DirCacheBuildIterator(builder));
walk.addTree(workingTree); walk.addTree(workingTree);
workingTree.setDirCacheIterator(walk, dciPos);
while (walk.next()) { while (walk.next()) {
processEntry(walk.getTree(0, CanonicalTreeParser.class), processEntry(walk.getTree(0, CanonicalTreeParser.class),
@ -1093,8 +1095,10 @@ private void cleanUpConflicts() throws CheckoutConflictException {
private boolean isModifiedSubtree_IndexWorkingtree(String path) private boolean isModifiedSubtree_IndexWorkingtree(String path)
throws CorruptObjectException, IOException { throws CorruptObjectException, IOException {
try (NameConflictTreeWalk tw = new NameConflictTreeWalk(repo)) { try (NameConflictTreeWalk tw = new NameConflictTreeWalk(repo)) {
tw.addTree(new DirCacheIterator(dc)); int dciPos = tw.addTree(new DirCacheIterator(dc));
tw.addTree(new FileTreeIterator(repo)); FileTreeIterator fti = new FileTreeIterator(repo);
tw.addTree(fti);
fti.setDirCacheIterator(tw, dciPos);
tw.setRecursive(true); tw.setRecursive(true);
tw.setFilter(PathFilter.create(path)); tw.setFilter(PathFilter.create(path));
DirCacheIterator dcIt; DirCacheIterator dcIt;

View File

@ -312,11 +312,10 @@ public Ref getRef(final String needle) throws IOException {
@Override @Override
public Map<String, Ref> getRefs(String prefix) throws IOException { public Map<String, Ref> getRefs(String prefix) throws IOException {
final RefList<Ref> packed = getPackedRefs();
final RefList<LooseRef> oldLoose = looseRefs.get(); final RefList<LooseRef> oldLoose = looseRefs.get();
LooseScanner scan = new LooseScanner(oldLoose); LooseScanner scan = new LooseScanner(oldLoose);
scan.scan(prefix); scan.scan(prefix);
final RefList<Ref> packed = getPackedRefs();
RefList<LooseRef> loose; RefList<LooseRef> loose;
if (scan.newLoose != null) { if (scan.newLoose != null) {

View File

@ -1005,13 +1005,14 @@ protected boolean mergeTrees(AbstractTreeIterator baseTree,
builder = dircache.builder(); builder = dircache.builder();
DirCacheBuildIterator buildIt = new DirCacheBuildIterator(builder); DirCacheBuildIterator buildIt = new DirCacheBuildIterator(builder);
tw = new NameConflictTreeWalk(reader); tw = new NameConflictTreeWalk(db, reader);
tw.addTree(baseTree); tw.addTree(baseTree);
tw.addTree(headTree); tw.addTree(headTree);
tw.addTree(mergeTree); tw.addTree(mergeTree);
tw.addTree(buildIt); int dciPos = tw.addTree(buildIt);
if (workingTreeIterator != null) { if (workingTreeIterator != null) {
tw.addTree(workingTreeIterator); tw.addTree(workingTreeIterator);
workingTreeIterator.setDirCacheIterator(tw, dciPos);
} else { } else {
tw.setFilter(TreeFilter.ANY_DIFF); tw.setFilter(TreeFilter.ANY_DIFF);
} }

View File

@ -106,7 +106,7 @@ private static class InCoreMerger extends ThreeWayMerger {
InCoreMerger(final Repository local) { InCoreMerger(final Repository local) {
super(local); super(local);
tw = new NameConflictTreeWalk(reader); tw = new NameConflictTreeWalk(local, reader);
cache = DirCache.newInCore(); cache = DirCache.newInCore();
} }

View File

@ -189,7 +189,8 @@ public static int response(final HttpConnection c) throws IOException {
try { try {
return c.getResponseCode(); return c.getResponseCode();
} catch (ConnectException ce) { } catch (ConnectException ce) {
final String host = c.getURL().getHost(); final URL url = c.getURL();
final String host = (url == null) ? "<null>" : url.getHost();
// The standard J2SE error message is not very useful. // The standard J2SE error message is not very useful.
// //
if ("Connection timed out: connect".equals(ce.getMessage())) //$NON-NLS-1$ if ("Connection timed out: connect".equals(ce.getMessage())) //$NON-NLS-1$
@ -216,7 +217,8 @@ public static int response(final java.net.HttpURLConnection c)
try { try {
return c.getResponseCode(); return c.getResponseCode();
} catch (ConnectException ce) { } catch (ConnectException ce) {
final String host = c.getURL().getHost(); final URL url = c.getURL();
final String host = (url == null) ? "<null>" : url.getHost();
// The standard J2SE error message is not very useful. // The standard J2SE error message is not very useful.
// //
if ("Connection timed out: connect".equals(ce.getMessage())) //$NON-NLS-1$ if ("Connection timed out: connect".equals(ce.getMessage())) //$NON-NLS-1$