summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/StatusTest.java6
-rw-r--r--org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/CLIText.properties10
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Archive.java133
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CLIText.java12
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Status.java50
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/archive/ArchiveCommand.java273
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/IndexDiffTest.java48
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtilTest.java85
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/api/Status.java12
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/api/TagCommand.java17
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffConfig.java24
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java30
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java138
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/RefUpdate.java2
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/merge/RecursiveMerger.java3
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevTag.java10
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/transport/RefSpec.java16
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/treewalk/AbstractTreeIterator.java9
18 files changed, 629 insertions, 249 deletions
diff --git a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/StatusTest.java b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/StatusTest.java
index 13f8c319c1..73ae598a8c 100644
--- a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/StatusTest.java
+++ b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/StatusTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012, François Rey <eclipse.org_@_francois_._rey_._name>
+ * Copyright (C) 2012, 2013 François Rey <eclipse.org_@_francois_._rey_._name>
* and other copyright owners as documented in the project's IP log.
*
* This program and the accompanying materials are made available
@@ -191,7 +191,7 @@ public class StatusTest extends CLIRepositoryTestCase {
"# On branch master", //
"# Unmerged paths:", //
"# ", //
- "# \tunmerged", //
+ "# \tboth modified: unmerged", //
"# ", //
"# Untracked files:", //
"# ", //
@@ -205,7 +205,7 @@ public class StatusTest extends CLIRepositoryTestCase {
"# Not currently on any branch.", //
"# Unmerged paths:", //
"# ", //
- "# \tunmerged", //
+ "# \tboth modified: unmerged", //
"# ", //
"# Untracked files:", //
"# ", //
diff --git a/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/CLIText.properties b/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/CLIText.properties
index 43b6f17768..3d6952bc93 100644
--- a/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/CLIText.properties
+++ b/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/CLIText.properties
@@ -7,7 +7,6 @@ N=N
alreadyOnBranch=Already on ''{0}''
alreadyUpToDate=Already up-to-date.
-archiveEntryModeIgnored=warning: mode of {0} ignored
authorInfo=Author: {0} <{1}>
averageMSPerRead=average {0} ms/read
branchAlreadyExists=A branch named ''{0}'' already exists.
@@ -48,6 +47,7 @@ deletedRemoteBranch=Deleted remote branch {0}
doesNotExist={0} does not exist
dontOverwriteLocalChanges=error: Your local changes to the following file would be overwritten by merge:
everythingUpToDate=Everything up-to-date
+exceptionCaughtDuringExecutionOfArchiveCommand=Exception caught during execution of archive command
expectedNumberOfbytes=Expected {0} bytes.
exporting=Exporting {0}
failedToCommitIndex=failed to commit index
@@ -153,9 +153,17 @@ serviceNotSupported=Service ''{0}'' not supported
skippingObject=skipping {0} {1}
statusFileListFormat=\t%1$s
statusFileListFormatWithPrefix=\t%1$-11s %2$s
+statusFileListFormatUnmerged=\t%1$-20s%2$s
statusModified=modified:
statusNewFile=new file:
statusRemoved=deleted:
+statusBothDeleted=both deleted:
+statusAddedByUs=added by us:
+statusDeletedByThem=deleted by them:
+statusAddedByThem=added by them:
+statusDeletedByUs=deleted by us:
+statusBothAdded=both added:
+statusBothModified=both modified:
switchedToNewBranch=Switched to a new branch ''{0}''
switchedToBranch=Switched to branch ''{0}''
tagAlreadyExists=tag ''{0}'' already exists
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Archive.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Archive.java
index 963528d106..5685aa4267 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Archive.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Archive.java
@@ -43,144 +43,33 @@
package org.eclipse.jgit.pgm;
-import java.lang.String;
-import java.lang.System;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.EnumMap;
-import java.util.Map;
-import java.text.MessageFormat;
-
-import org.apache.commons.compress.archivers.ArchiveOutputStream;
-import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
-import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
-import org.apache.commons.compress.archivers.tar.TarConstants;
-import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
-import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
-import org.eclipse.jgit.lib.FileMode;
-import org.eclipse.jgit.lib.MutableObjectId;
-import org.eclipse.jgit.lib.ObjectLoader;
-import org.eclipse.jgit.lib.ObjectReader;
+import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.pgm.CLIText;
import org.eclipse.jgit.pgm.TextBuiltin;
-import org.eclipse.jgit.treewalk.AbstractTreeIterator;
-import org.eclipse.jgit.treewalk.TreeWalk;
+import org.eclipse.jgit.pgm.archive.ArchiveCommand;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;
@Command(common = true, usage = "usage_archive")
class Archive extends TextBuiltin {
@Argument(index = 0, metaVar = "metaVar_treeish")
- private AbstractTreeIterator tree;
+ private ObjectId tree;
@Option(name = "--format", metaVar = "metaVar_archiveFormat", usage = "usage_archiveFormat")
- private Format format = Format.ZIP;
+ private ArchiveCommand.Format format = ArchiveCommand.Format.ZIP;
@Override
protected void run() throws Exception {
- final TreeWalk walk = new TreeWalk(db);
- final ObjectReader reader = walk.getObjectReader();
- final MutableObjectId idBuf = new MutableObjectId();
- final Archiver fmt = formats.get(format);
- final ArchiveOutputStream outa = fmt.createArchiveOutputStream(outs);
-
if (tree == null)
throw die(CLIText.get().treeIsRequired);
- walk.reset();
- walk.addTree(tree);
- walk.setRecursive(true);
- while (walk.next()) {
- final String name = walk.getPathString();
- final FileMode mode = walk.getFileMode(0);
-
- if (mode == FileMode.TREE)
- // ZIP entries for directories are optional.
- // Leave them out, mimicking "git archive".
- continue;
-
- walk.getObjectId(idBuf, 0);
- fmt.putEntry(name, mode, reader.open(idBuf), outa);
+ final ArchiveCommand cmd = new ArchiveCommand(db);
+ try {
+ cmd.setTree(tree)
+ .setFormat(format)
+ .setOutputStream(outs).call();
+ } finally {
+ cmd.release();
}
-
- outa.close();
- }
-
- static private void warnArchiveEntryModeIgnored(String name) {
- System.err.println(MessageFormat.format( //
- CLIText.get().archiveEntryModeIgnored, //
- name));
- }
-
- public enum Format {
- ZIP,
- TAR
- }
-
- private static interface Archiver {
- ArchiveOutputStream createArchiveOutputStream(OutputStream s);
- void putEntry(String path, FileMode mode, //
- ObjectLoader loader, ArchiveOutputStream out) //
- throws IOException;
- }
-
- private static final Map<Format, Archiver> formats;
- static {
- Map<Format, Archiver> fmts = new EnumMap<Format, Archiver>(Format.class);
- fmts.put(Format.ZIP, new Archiver() {
- public ArchiveOutputStream createArchiveOutputStream(OutputStream s) {
- return new ZipArchiveOutputStream(s);
- }
-
- public void putEntry(String path, FileMode mode, //
- ObjectLoader loader, ArchiveOutputStream out) //
- throws IOException {
- final ZipArchiveEntry entry = new ZipArchiveEntry(path);
-
- if (mode == FileMode.REGULAR_FILE) {
- // ok
- } else if (mode == FileMode.EXECUTABLE_FILE
- || mode == FileMode.SYMLINK) {
- entry.setUnixMode(mode.getBits());
- } else {
- warnArchiveEntryModeIgnored(path);
- }
- entry.setSize(loader.getSize());
- out.putArchiveEntry(entry);
- loader.copyTo(out);
- out.closeArchiveEntry();
- }
- });
- fmts.put(Format.TAR, new Archiver() {
- public ArchiveOutputStream createArchiveOutputStream(OutputStream s) {
- return new TarArchiveOutputStream(s);
- }
-
- public void putEntry(String path, FileMode mode, //
- ObjectLoader loader, ArchiveOutputStream out) //
- throws IOException {
- if (mode == FileMode.SYMLINK) {
- final TarArchiveEntry entry = new TarArchiveEntry( //
- path, TarConstants.LF_SYMLINK);
- entry.setLinkName(new String( //
- loader.getCachedBytes(100), "UTF-8")); //$NON-NLS-1$
- out.putArchiveEntry(entry);
- out.closeArchiveEntry();
- return;
- }
-
- final TarArchiveEntry entry = new TarArchiveEntry(path);
- if (mode == FileMode.REGULAR_FILE ||
- mode == FileMode.EXECUTABLE_FILE)
- entry.setMode(mode.getBits());
- else
- warnArchiveEntryModeIgnored(path);
- entry.setSize(loader.getSize());
- out.putArchiveEntry(entry);
- loader.copyTo(out);
- out.closeArchiveEntry();
- }
- });
- formats = fmts;
}
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CLIText.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CLIText.java
index 1f14fa272b..c6f913c681 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CLIText.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CLIText.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010, 2012 Sasa Zivkov <sasa.zivkov@sap.com>
+ * Copyright (C) 2010, 2013 Sasa Zivkov <sasa.zivkov@sap.com>
* and other copyright owners as documented in the project's IP log.
*
* This program and the accompanying materials are made available
@@ -76,7 +76,6 @@ public class CLIText extends TranslationBundle {
// @formatter:off
/***/ public String alreadyOnBranch;
/***/ public String alreadyUpToDate;
- /***/ public String archiveEntryModeIgnored;
/***/ public String authorInfo;
/***/ public String averageMSPerRead;
/***/ public String branchAlreadyExists;
@@ -117,6 +116,7 @@ public class CLIText extends TranslationBundle {
/***/ public String doesNotExist;
/***/ public String dontOverwriteLocalChanges;
/***/ public String everythingUpToDate;
+ /***/ public String exceptionCaughtDuringExecutionOfArchiveCommand;
/***/ public String expectedNumberOfbytes;
/***/ public String exporting;
/***/ public String failedToCommitIndex;
@@ -216,9 +216,17 @@ public class CLIText extends TranslationBundle {
/***/ public String skippingObject;
/***/ public String statusFileListFormat;
/***/ public String statusFileListFormatWithPrefix;
+ /***/ public String statusFileListFormatUnmerged;
/***/ public String statusModified;
/***/ public String statusNewFile;
/***/ public String statusRemoved;
+ /***/ public String statusBothDeleted;
+ /***/ public String statusAddedByUs;
+ /***/ public String statusDeletedByThem;
+ /***/ public String statusAddedByThem;
+ /***/ public String statusDeletedByUs;
+ /***/ public String statusBothAdded;
+ /***/ public String statusBothModified;
/***/ public String switchedToNewBranch;
/***/ public String switchedToBranch;
/***/ public String tagAlreadyExists;
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Status.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Status.java
index 4d2308e214..c1b635ca9f 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Status.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Status.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011, François Rey <eclipse.org_@_francois_._rey_._name>
+ * Copyright (C) 2011, 2013 François Rey <eclipse.org_@_francois_._rey_._name>
* and other copyright owners as documented in the project's IP log.
*
* This program and the accompanying materials are made available
@@ -47,10 +47,13 @@ import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.List;
+import java.util.Map;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.IndexDiff.StageState;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
@@ -63,6 +66,8 @@ class Status extends TextBuiltin {
protected final String statusFileListFormatWithPrefix = CLIText.get().statusFileListFormatWithPrefix;
+ protected final String statusFileListFormatUnmerged = CLIText.get().statusFileListFormatUnmerged;
+
@Override
protected void run() throws Exception {
// Print current branch name
@@ -82,7 +87,8 @@ class Status extends TextBuiltin {
Collection<String> modified = status.getModified();
Collection<String> missing = status.getMissing();
Collection<String> untracked = status.getUntracked();
- Collection<String> unmerged = status.getConflicting();
+ Map<String, StageState> unmergedStates = status
+ .getConflictingStageState();
Collection<String> toBeCommitted = new ArrayList<String>(added);
toBeCommitted.addAll(changed);
toBeCommitted.addAll(removed);
@@ -106,12 +112,12 @@ class Status extends TextBuiltin {
modified, missing, null);
firstHeader = false;
}
- int nbUnmerged = unmerged.size();
+ int nbUnmerged = unmergedStates.size();
if (nbUnmerged > 0) {
if (!firstHeader)
printSectionHeader(""); //$NON-NLS-1$
printSectionHeader(CLIText.get().unmergedPaths);
- printList(unmerged);
+ printUnmerged(unmergedStates);
firstHeader = false;
}
int nbUntracked = untracked.size();
@@ -168,4 +174,40 @@ class Status extends TextBuiltin {
}
return list.size();
}
+
+ private void printUnmerged(Map<String, StageState> unmergedStates)
+ throws IOException {
+ List<String> paths = new ArrayList<String>(unmergedStates.keySet());
+ Collections.sort(paths);
+ for (String path : paths) {
+ StageState state = unmergedStates.get(path);
+ String stateDescription = getStageStateDescription(state);
+ outw.println(CLIText.formatLine(String.format(
+ statusFileListFormatUnmerged, stateDescription, path)));
+ outw.flush();
+ }
+ }
+
+ private static String getStageStateDescription(StageState stageState) {
+ CLIText text = CLIText.get();
+ switch (stageState) {
+ case BOTH_DELETED:
+ return text.statusBothDeleted;
+ case ADDED_BY_US:
+ return text.statusAddedByUs;
+ case DELETED_BY_THEM:
+ return text.statusDeletedByThem;
+ case ADDED_BY_THEM:
+ return text.statusAddedByThem;
+ case DELETED_BY_US:
+ return text.statusDeletedByUs;
+ case BOTH_ADDED:
+ return text.statusBothAdded;
+ case BOTH_MODIFIED:
+ return text.statusBothModified;
+ default:
+ throw new IllegalArgumentException("Unknown StageState: " //$NON-NLS-1$
+ + stageState);
+ }
+ }
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/archive/ArchiveCommand.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/archive/ArchiveCommand.java
new file mode 100644
index 0000000000..7c2e7c0993
--- /dev/null
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/archive/ArchiveCommand.java
@@ -0,0 +1,273 @@
+/*
+ * Copyright (C) 2012 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.pgm.archive;
+
+import java.lang.String;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.EnumMap;
+import java.util.Map;
+import java.text.MessageFormat;
+
+import org.apache.commons.compress.archivers.ArchiveOutputStream;
+import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
+import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
+import org.apache.commons.compress.archivers.tar.TarConstants;
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
+import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
+import org.eclipse.jgit.api.GitCommand;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.api.errors.JGitInternalException;
+import org.eclipse.jgit.lib.FileMode;
+import org.eclipse.jgit.lib.MutableObjectId;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ObjectLoader;
+import org.eclipse.jgit.lib.ObjectReader;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.pgm.CLIText;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.treewalk.TreeWalk;
+
+/**
+ * Create an archive of files from a named tree.
+ * <p>
+ * Examples (<code>git</code> is a {@link Git} instance):
+ * <p>
+ * Create a tarball from HEAD:
+ *
+ * <pre>
+ * cmd = new ArchiveCommand(git.getRepository());
+ * try {
+ * cmd.setTree(db.resolve(&quot;HEAD&quot;))
+ * .setOutputStream(out).call();
+ * } finally {
+ * cmd.release();
+ * }
+ * </pre>
+ * <p>
+ * Create a ZIP file from master:
+ *
+ * <pre>
+ * try {
+ * cmd.setTree(db.resolve(&quot;master&quot;))
+ * .setFormat(ArchiveCommand.Format.ZIP)
+ * .setOutputStream(out).call();
+ * } finally {
+ * cmd.release();
+ * }
+ * </pre>
+ *
+ * @see <a href="http://git-htmldocs.googlecode.com/git/git-archive.html"
+ * >Git documentation about archive</a>
+ */
+public class ArchiveCommand extends GitCommand<OutputStream> {
+ /**
+ * Available archival formats (corresponding to values for
+ * the --format= option)
+ */
+ public static enum Format {
+ ZIP,
+ TAR
+ }
+
+ private static interface Archiver {
+ ArchiveOutputStream createArchiveOutputStream(OutputStream s);
+ void putEntry(String path, FileMode mode, //
+ ObjectLoader loader, ArchiveOutputStream out) //
+ throws IOException;
+ }
+
+ private static final Map<Format, Archiver> formats;
+
+ static {
+ Map<Format, Archiver> fmts = new EnumMap<Format, Archiver>(Format.class);
+ fmts.put(Format.ZIP, new Archiver() {
+ public ArchiveOutputStream createArchiveOutputStream(OutputStream s) {
+ return new ZipArchiveOutputStream(s);
+ }
+
+ public void putEntry(String path, FileMode mode, //
+ ObjectLoader loader, ArchiveOutputStream out) //
+ throws IOException {
+ final ZipArchiveEntry entry = new ZipArchiveEntry(path);
+
+ if (mode == FileMode.REGULAR_FILE) {
+ // ok
+ } else if (mode == FileMode.EXECUTABLE_FILE
+ || mode == FileMode.SYMLINK) {
+ entry.setUnixMode(mode.getBits());
+ } else {
+ // TODO(jrn): Let the caller know the tree contained
+ // an entry with unsupported mode (e.g., a submodule).
+ }
+ entry.setSize(loader.getSize());
+ out.putArchiveEntry(entry);
+ loader.copyTo(out);
+ out.closeArchiveEntry();
+ }
+ });
+ fmts.put(Format.TAR, new Archiver() {
+ public ArchiveOutputStream createArchiveOutputStream(OutputStream s) {
+ return new TarArchiveOutputStream(s);
+ }
+
+ public void putEntry(String path, FileMode mode, //
+ ObjectLoader loader, ArchiveOutputStream out) //
+ throws IOException {
+ if (mode == FileMode.SYMLINK) {
+ final TarArchiveEntry entry = new TarArchiveEntry( //
+ path, TarConstants.LF_SYMLINK);
+ entry.setLinkName(new String( //
+ loader.getCachedBytes(100), "UTF-8")); //$NON-NLS-1$
+ out.putArchiveEntry(entry);
+ out.closeArchiveEntry();
+ return;
+ }
+
+ final TarArchiveEntry entry = new TarArchiveEntry(path);
+ if (mode == FileMode.REGULAR_FILE ||
+ mode == FileMode.EXECUTABLE_FILE) {
+ entry.setMode(mode.getBits());
+ } else {
+ // TODO(jrn): Let the caller know the tree contained
+ // an entry with unsupported mode (e.g., a submodule).
+ }
+ entry.setSize(loader.getSize());
+ out.putArchiveEntry(entry);
+ loader.copyTo(out);
+ out.closeArchiveEntry();
+ }
+ });
+ formats = fmts;
+ }
+
+ private OutputStream out;
+ private TreeWalk walk;
+ private Format format = Format.TAR;
+
+ /**
+ * @param repo
+ */
+ public ArchiveCommand(Repository repo) {
+ super(repo);
+ walk = new TreeWalk(repo);
+ }
+
+ /**
+ * Release any resources used by the internal ObjectReader.
+ * <p>
+ * This does not close the output stream set with setOutputStream, which
+ * belongs to the caller.
+ */
+ public void release() {
+ walk.release();
+ }
+
+ /**
+ * @return the stream to which the archive has been written
+ */
+ @Override
+ public OutputStream call() throws GitAPIException {
+ final MutableObjectId idBuf = new MutableObjectId();
+ final Archiver fmt = formats.get(format);
+ final ArchiveOutputStream outa = fmt.createArchiveOutputStream(out);
+ final ObjectReader reader = walk.getObjectReader();
+
+ try {
+ try {
+ walk.setRecursive(true);
+ while (walk.next()) {
+ final String name = walk.getPathString();
+ final FileMode mode = walk.getFileMode(0);
+
+ if (mode == FileMode.TREE)
+ // ZIP entries for directories are optional.
+ // Leave them out, mimicking "git archive".
+ continue;
+
+ walk.getObjectId(idBuf, 0);
+ fmt.putEntry(name, mode, reader.open(idBuf), outa);
+ }
+ } finally {
+ outa.close();
+ }
+ } catch (IOException e) {
+ // TODO(jrn): Throw finer-grained errors.
+ throw new JGitInternalException(
+ CLIText.get().exceptionCaughtDuringExecutionOfArchiveCommand, e);
+ }
+
+ return out;
+ }
+
+ /**
+ * @param tree
+ * the tag, commit, or tree object to produce an archive for
+ * @return this
+ */
+ public ArchiveCommand setTree(ObjectId tree) throws IOException {
+ final RevWalk rw = new RevWalk(walk.getObjectReader());
+ walk.reset(rw.parseTree(tree));
+ return this;
+ }
+
+ /**
+ * @param out
+ * the stream to which to write the archive
+ * @return this
+ */
+ public ArchiveCommand setOutputStream(OutputStream out) {
+ this.out = out;
+ return this;
+ }
+
+ /**
+ * @param fmt
+ * archive format (e.g., Format.TAR)
+ * @return this
+ */
+ public ArchiveCommand setFormat(Format fmt) {
+ this.format = fmt;
+ return this;
+ }
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/IndexDiffTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/IndexDiffTest.java
index 6040dfed78..51ba5f13ea 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/IndexDiffTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/IndexDiffTest.java
@@ -2,6 +2,7 @@
* Copyright (C) 2007, Dave Watson <dwatson@mimvista.com>
* Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
* Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
+ * Copyright (C) 2013, Robin Stocker <robin@nibor.org>
* and other copyright owners as documented in the project's IP log.
*
* This program and the accompanying materials are made available
@@ -46,6 +47,7 @@
package org.eclipse.jgit.lib;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.io.File;
@@ -61,10 +63,12 @@ import org.eclipse.jgit.api.MergeResult;
import org.eclipse.jgit.api.MergeResult.MergeStatus;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.dircache.DirCache;
+import org.eclipse.jgit.dircache.DirCacheBuilder;
import org.eclipse.jgit.dircache.DirCacheEditor;
import org.eclipse.jgit.dircache.DirCacheEditor.PathEdit;
import org.eclipse.jgit.dircache.DirCacheEntry;
import org.eclipse.jgit.junit.RepositoryTestCase;
+import org.eclipse.jgit.lib.IndexDiff.StageState;
import org.eclipse.jgit.merge.MergeStrategy;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.treewalk.FileTreeIterator;
@@ -212,6 +216,8 @@ public class IndexDiffTest extends RepositoryTestCase {
assertEquals("[]", diff.getMissing().toString());
assertEquals("[]", diff.getModified().toString());
assertEquals("[a]", diff.getConflicting().toString());
+ assertEquals(StageState.BOTH_MODIFIED,
+ diff.getConflictingStageStates().get("a"));
assertEquals(Collections.EMPTY_SET, diff.getUntrackedFolders());
}
@@ -251,6 +257,8 @@ public class IndexDiffTest extends RepositoryTestCase {
assertEquals("[]", diff.getMissing().toString());
assertEquals("[]", diff.getModified().toString());
assertEquals("[a]", diff.getConflicting().toString());
+ assertEquals(StageState.DELETED_BY_THEM,
+ diff.getConflictingStageStates().get("a"));
assertEquals(Collections.EMPTY_SET, diff.getUntrackedFolders());
}
@@ -500,6 +508,46 @@ public class IndexDiffTest extends RepositoryTestCase {
assertEquals(Collections.EMPTY_SET, diff.getUntrackedFolders());
}
+ @Test
+ public void testStageState() throws IOException {
+ final int base = DirCacheEntry.STAGE_1;
+ final int ours = DirCacheEntry.STAGE_2;
+ final int theirs = DirCacheEntry.STAGE_3;
+ verifyStageState(StageState.BOTH_DELETED, base);
+ verifyStageState(StageState.DELETED_BY_THEM, ours, base);
+ verifyStageState(StageState.DELETED_BY_US, base, theirs);
+ verifyStageState(StageState.BOTH_MODIFIED, base, ours, theirs);
+ verifyStageState(StageState.ADDED_BY_US, ours);
+ verifyStageState(StageState.BOTH_ADDED, ours, theirs);
+ verifyStageState(StageState.ADDED_BY_THEM, theirs);
+
+ assertTrue(StageState.BOTH_DELETED.hasBase());
+ assertFalse(StageState.BOTH_DELETED.hasOurs());
+ assertFalse(StageState.BOTH_DELETED.hasTheirs());
+ assertFalse(StageState.BOTH_ADDED.hasBase());
+ assertTrue(StageState.BOTH_ADDED.hasOurs());
+ assertTrue(StageState.BOTH_ADDED.hasTheirs());
+ }
+
+ private void verifyStageState(StageState expected, int... stages)
+ throws IOException {
+ DirCacheBuilder builder = db.lockDirCache().builder();
+ for (int stage : stages) {
+ DirCacheEntry entry = createEntry("a", FileMode.REGULAR_FILE,
+ stage, "content");
+ builder.add(entry);
+ }
+ builder.commit();
+
+ IndexDiff diff = new IndexDiff(db, Constants.HEAD,
+ new FileTreeIterator(db));
+ diff.diff();
+
+ assertEquals(
+ "Conflict for entries in stages " + Arrays.toString(stages),
+ expected, diff.getConflictingStageStates().get("a"));
+ }
+
private void removeFromIndex(String path) throws IOException {
final DirCache dirc = db.lockDirCache();
final DirCacheEditor edit = dirc.editor();
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtilTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtilTest.java
index f6f6753c75..3cd01453a1 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtilTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtilTest.java
@@ -119,91 +119,6 @@ public class FileUtilTest {
}
@Test
- public void testDeleteRecursiveEmpty() throws IOException {
- File f1 = new File(trash, "test/test/a");
- File f2 = new File(trash, "test/a");
- File d1 = new File(trash, "test");
- File d2 = new File(trash, "test/test");
- File d3 = new File(trash, "test/b");
- FileUtils.mkdirs(f1.getParentFile());
- FileUtils.createNewFile(f2);
- FileUtils.createNewFile(f1);
- FileUtils.mkdirs(d3);
-
- // Cannot delete hierarchy since files exist
- try {
- FileUtils.delete(d1, FileUtils.EMPTY_DIRECTORIES_ONLY);
- fail("delete should fail");
- } catch (IOException e1) {
- try {
- FileUtils.delete(d1, FileUtils.EMPTY_DIRECTORIES_ONLY|FileUtils.RECURSIVE);
- fail("delete should fail");
- } catch (IOException e2) {
- // Everything still there
- assertTrue(f1.exists());
- assertTrue(f2.exists());
- assertTrue(d1.exists());
- assertTrue(d2.exists());
- assertTrue(d3.exists());
- }
- }
-
- // setup: delete files, only directories left
- assertTrue(f1.delete());
- assertTrue(f2.delete());
-
- // Shall not delete hierarchy without recursive
- try {
- FileUtils.delete(d1, FileUtils.EMPTY_DIRECTORIES_ONLY);
- fail("delete should fail");
- } catch (IOException e2) {
- // Everything still there
- assertTrue(d1.exists());
- assertTrue(d2.exists());
- assertTrue(d3.exists());
- }
-
- // Now delete the empty hierarchy
- FileUtils.delete(d2, FileUtils.EMPTY_DIRECTORIES_ONLY
- | FileUtils.RECURSIVE);
- assertFalse(d2.exists());
-
- // Will fail to delete non-existing without SKIP_MISSING
- try {
- FileUtils.delete(d2, FileUtils.EMPTY_DIRECTORIES_ONLY);
- fail("Cannot delete non-existent entity");
- } catch (IOException e) {
- // ok
- }
-
- // ..with SKIP_MISSING there is no exception
- FileUtils.delete(d2, FileUtils.EMPTY_DIRECTORIES_ONLY
- | FileUtils.SKIP_MISSING);
- FileUtils.delete(d2, FileUtils.EMPTY_DIRECTORIES_ONLY
- | FileUtils.RECURSIVE | FileUtils.SKIP_MISSING);
-
- // essentially the same, using IGNORE_ERRORS
- FileUtils.delete(d2, FileUtils.EMPTY_DIRECTORIES_ONLY
- | FileUtils.IGNORE_ERRORS);
- FileUtils.delete(d2, FileUtils.EMPTY_DIRECTORIES_ONLY
- | FileUtils.RECURSIVE | FileUtils.IGNORE_ERRORS);
- }
-
- @Test
- public void testDeleteRecursiveEmptyDirectoriesOnlyButIsFile()
- throws IOException {
- File f1 = new File(trash, "test/test/a");
- FileUtils.mkdirs(f1.getParentFile());
- FileUtils.createNewFile(f1);
- try {
- FileUtils.delete(f1, FileUtils.EMPTY_DIRECTORIES_ONLY);
- fail("delete should fail");
- } catch (IOException e) {
- assertTrue(f1.exists());
- }
- }
-
- @Test
public void testMkdir() throws IOException {
File d = new File(trash, "test");
FileUtils.mkdir(d);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/Status.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/Status.java
index cb2ae6bf01..e840c2f608 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/Status.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/Status.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011, Christian Halstrick <christian.halstrick@sap.com>
+ * Copyright (C) 2011, 2013 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
@@ -43,9 +43,11 @@
package org.eclipse.jgit.api;
import java.util.Collections;
+import java.util.Map;
import java.util.Set;
import org.eclipse.jgit.lib.IndexDiff;
+import org.eclipse.jgit.lib.IndexDiff.StageState;
/**
* A class telling where the working-tree, the index and the current HEAD differ
@@ -153,6 +155,14 @@ public class Status {
}
/**
+ * @return a map from conflicting path to its {@link StageState}.
+ * @since 3.0
+ */
+ public Map<String, StageState> getConflictingStageState() {
+ return Collections.unmodifiableMap(diff.getConflictingStageStates());
+ }
+
+ /**
* @return set of files and folders that are ignored and not in the index.
*/
public Set<String> getIgnoredNotInIndex() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/TagCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/TagCommand.java
index 1784acd79b..3b1fe88409 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/TagCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/TagCommand.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010, Chris Aniszczyk <caniszczyk@gmail.com>
+ * Copyright (C) 2010, 2013 Chris Aniszczyk <caniszczyk@gmail.com>
* and other copyright owners as documented in the project's IP log.
*
* This program and the accompanying materials are made available
@@ -66,9 +66,18 @@ import org.eclipse.jgit.revwalk.RevObject;
import org.eclipse.jgit.revwalk.RevWalk;
/**
- * A class used to execute a {@code Tag} command. It has setters for all
- * supported options and arguments of this command and a {@link #call()} method
- * to finally execute the command.
+ * Create/update an annotated tag object.
+ * <p>
+ * Examples (<code>git</code> is a {@link Git} instance):
+ * <p>
+ * Create a new annotated tag for the current commit:
+ *
+ * <pre>
+ * git.tag().setName(&quot;v1.0&quot;).setMessage(&quot;First stable release&quot;).call();
+ * </pre>
+ * <p>
+ * Use {@link Repository#updateRef(String)} to create a lightweight tag (just a
+ * named reference to a commit).
*
* @see <a href="http://www.kernel.org/pub/software/scm/git/docs/git-tag.html"
* >Git documentation about Tag</a>
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffConfig.java
index 13874004d5..b1cbb914d8 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffConfig.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffConfig.java
@@ -48,6 +48,7 @@ import java.text.MessageFormat;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.Config.SectionParser;
+import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.util.StringUtils;
/** Keeps track of diff related configuration options. */
@@ -78,10 +79,12 @@ public class DiffConfig {
private final int renameLimit;
private DiffConfig(final Config rc) {
- noPrefix = rc.getBoolean("diff", "noprefix", false); //$NON-NLS-1$ //$NON-NLS-2$
- renameDetectionType = parseRenameDetectionType(rc.getString("diff", //$NON-NLS-1$
- null, "renames")); //$NON-NLS-1$
- renameLimit = rc.getInt("diff", "renamelimit", 200); //$NON-NLS-1$ //$NON-NLS-2$
+ noPrefix = rc.getBoolean(ConfigConstants.CONFIG_DIFF_SECTION,
+ ConfigConstants.CONFIG_KEY_NOPREFIX, false);
+ renameDetectionType = parseRenameDetectionType(rc.getString(
+ ConfigConstants.CONFIG_DIFF_SECTION, null, ConfigConstants.CONFIG_KEY_RENAMES));
+ renameLimit = rc.getInt(ConfigConstants.CONFIG_DIFF_SECTION,
+ ConfigConstants.CONFIG_KEY_RENAMELIMIT, 200);
}
/** @return true if the prefix "a/" and "b/" should be suppressed. */
@@ -108,16 +111,21 @@ public class DiffConfig {
final String renameString) {
if (renameString == null)
return RenameDetectionType.FALSE;
- else if (StringUtils.equalsIgnoreCase("copy", renameString) //$NON-NLS-1$
- || StringUtils.equalsIgnoreCase("copies", renameString)) //$NON-NLS-1$
+ else if (StringUtils.equalsIgnoreCase(
+ ConfigConstants.CONFIG_RENAMELIMIT_COPY, renameString)
+ || StringUtils
+ .equalsIgnoreCase(
+ ConfigConstants.CONFIG_RENAMELIMIT_COPIES,
+ renameString))
return RenameDetectionType.COPY;
else {
final Boolean renameBoolean = StringUtils
.toBooleanOrNull(renameString);
if (renameBoolean == null)
throw new IllegalArgumentException(MessageFormat.format(
- JGitText.get().enumValueNotSupported2, "diff", //$NON-NLS-1$
- "renames", renameString)); //$NON-NLS-1$
+ JGitText.get().enumValueNotSupported2,
+ ConfigConstants.CONFIG_DIFF_SECTION,
+ ConfigConstants.CONFIG_KEY_RENAMES, renameString));
else if (renameBoolean.booleanValue())
return RenameDetectionType.TRUE;
else
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
index fc0e06a700..3ff4eefb1c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
@@ -195,4 +195,34 @@ public class ConfigConstants {
* @since 3.0
*/
public static final String CONFIG_KEY_CHECKSTAT = "checkstat";
+
+ /**
+ * The "renamelimit" key in the "diff section"
+ * @since 3.0
+ */
+ public static final String CONFIG_KEY_RENAMELIMIT = "renamelimit";
+
+ /**
+ * The "noprefix" key in the "diff section"
+ * @since 3.0
+ */
+ public static final String CONFIG_KEY_NOPREFIX = "noprefix";
+
+ /**
+ * A "renamelimit" value in the "diff section"
+ * @since 3.0
+ */
+ public static final String CONFIG_RENAMELIMIT_COPY = "copy";
+
+ /**
+ * A "renamelimit" value in the "diff section"
+ * @since 3.0
+ */
+ public static final String CONFIG_RENAMELIMIT_COPIES = "copies";
+
+ /**
+ * The "renames" key in the "diff section"
+ * @since 3.0
+ */
+ public static final String CONFIG_KEY_RENAMES = "renames";
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java
index d32eb99792..33654447ae 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java
@@ -2,6 +2,7 @@
* Copyright (C) 2007, Dave Watson <dwatson@mimvista.com>
* Copyright (C) 2007-2008, Robin Rosenberg <robin.rosenberg@dewire.com>
* Copyright (C) 2010, Jens Baumgart <jens.baumgart@sap.com>
+ * Copyright (C) 2013, Robin Stocker <robin@nibor.org>
* and other copyright owners as documented in the project's IP log.
*
* This program and the accompanying materials are made available
@@ -49,7 +50,9 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
import org.eclipse.jgit.dircache.DirCache;
@@ -85,6 +88,105 @@ import org.eclipse.jgit.treewalk.filter.TreeFilter;
*/
public class IndexDiff {
+ /**
+ * Represents the state of the index for a certain path regarding the stages
+ * - which stages exist for a path and which not (base, ours, theirs).
+ * <p>
+ * This is used for figuring out what kind of conflict occurred.
+ *
+ * @see IndexDiff#getConflictingStageStates()
+ * @since 3.0
+ */
+ public static enum StageState {
+ /**
+ * Exists in base, but neither in ours nor in theirs.
+ */
+ BOTH_DELETED(1),
+
+ /**
+ * Only exists in ours.
+ */
+ ADDED_BY_US(2),
+
+ /**
+ * Exists in base and ours, but no in theirs.
+ */
+ DELETED_BY_THEM(3),
+
+ /**
+ * Only exists in theirs.
+ */
+ ADDED_BY_THEM(4),
+
+ /**
+ * Exists in base and theirs, but not in ours.
+ */
+ DELETED_BY_US(5),
+
+ /**
+ * Exists in ours and theirs, but not in base.
+ */
+ BOTH_ADDED(6),
+
+ /**
+ * Exists in all stages, content conflict.
+ */
+ BOTH_MODIFIED(7);
+
+ private final int stageMask;
+
+ private StageState(int stageMask) {
+ this.stageMask = stageMask;
+ }
+
+ int getStageMask() {
+ return stageMask;
+ }
+
+ /**
+ * @return whether there is a "base" stage entry
+ */
+ public boolean hasBase() {
+ return (stageMask & 1) != 0;
+ }
+
+ /**
+ * @return whether there is an "ours" stage entry
+ */
+ public boolean hasOurs() {
+ return (stageMask & 2) != 0;
+ }
+
+ /**
+ * @return whether there is a "theirs" stage entry
+ */
+ public boolean hasTheirs() {
+ return (stageMask & 4) != 0;
+ }
+
+ static StageState fromMask(int stageMask) {
+ // bits represent: theirs, ours, base
+ switch (stageMask) {
+ case 1: // 0b001
+ return BOTH_DELETED;
+ case 2: // 0b010
+ return ADDED_BY_US;
+ case 3: // 0b011
+ return DELETED_BY_THEM;
+ case 4: // 0b100
+ return ADDED_BY_THEM;
+ case 5: // 0b101
+ return DELETED_BY_US;
+ case 6: // 0b110
+ return BOTH_ADDED;
+ case 7: // 0b111
+ return BOTH_MODIFIED;
+ default:
+ return null;
+ }
+ }
+ }
+
private static final class ProgressReportingFilter extends TreeFilter {
private final ProgressMonitor monitor;
@@ -156,7 +258,7 @@ public class IndexDiff {
private Set<String> untracked = new HashSet<String>();
- private Set<String> conflicts = new HashSet<String>();
+ private Map<String, StageState> conflicts = new HashMap<String, StageState>();
private Set<String> ignored;
@@ -295,9 +397,13 @@ public class IndexDiff {
if (dirCacheIterator != null) {
final DirCacheEntry dirCacheEntry = dirCacheIterator
.getDirCacheEntry();
- if (dirCacheEntry != null && dirCacheEntry.getStage() > 0) {
- conflicts.add(treeWalk.getPathString());
- continue;
+ if (dirCacheEntry != null) {
+ int stage = dirCacheEntry.getStage();
+ if (stage > 0) {
+ String path = treeWalk.getPathString();
+ addConflict(path, stage);
+ continue;
+ }
}
}
@@ -355,6 +461,18 @@ public class IndexDiff {
return true;
}
+ private void addConflict(String path, int stage) {
+ StageState existingStageStates = conflicts.get(path);
+ byte stageMask = 0;
+ if (existingStageStates != null)
+ stageMask |= existingStageStates.getStageMask();
+ // stage 1 (base) should be shifted 0 times
+ int shifts = stage - 1;
+ stageMask |= (1 << shifts);
+ StageState stageState = StageState.fromMask(stageMask);
+ conflicts.put(path, stageState);
+ }
+
/**
* @return list of files added to the index, not in the tree
*/
@@ -398,9 +516,19 @@ public class IndexDiff {
}
/**
- * @return list of files that are in conflict
+ * @return list of files that are in conflict, corresponds to the keys of
+ * {@link #getConflictingStageStates()}
*/
public Set<String> getConflicting() {
+ return conflicts.keySet();
+ }
+
+ /**
+ * @return the map from each path of {@link #getConflicting()} to its
+ * corresponding {@link StageState}
+ * @since 3.0
+ */
+ public Map<String, StageState> getConflictingStageStates() {
return conflicts;
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefUpdate.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefUpdate.java
index 9ef1722d7e..8d59cb47b4 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefUpdate.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefUpdate.java
@@ -531,7 +531,7 @@ public abstract class RefUpdate {
final String myName = getRef().getLeaf().getName();
if (myName.startsWith(Constants.R_HEADS)) {
Ref head = getRefDatabase().getRef(Constants.HEAD);
- while (head.isSymbolic()) {
+ while (head != null && head.isSymbolic()) {
head = head.getTarget();
if (myName.equals(head.getName()))
return result = Result.REJECTED_CURRENT_BRANCH;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/RecursiveMerger.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/RecursiveMerger.java
index 540d6a8c66..5802850a30 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/RecursiveMerger.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/RecursiveMerger.java
@@ -53,7 +53,6 @@ import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
-import java.util.logging.Logger;
import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.dircache.DirCacheBuilder;
@@ -85,8 +84,6 @@ import org.eclipse.jgit.treewalk.WorkingTreeIterator;
* @since 3.0
*/
public class RecursiveMerger extends ResolveMerger {
- static Logger log = Logger.getLogger(RecursiveMerger.class.toString());
-
/**
* The maximum number of merge bases. This merge will stop when the number
* of merge bases exceeds this value
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevTag.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevTag.java
index 269b6c104f..12693a03e2 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevTag.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevTag.java
@@ -240,8 +240,16 @@ public class RevTag extends RevObject {
/**
* Get a reference to the object this tag was placed on.
+ * <p>
+ * Note that the returned object has only been looked up (see
+ * {@link RevWalk#lookupAny(AnyObjectId, int)}. To access the contents it
+ * needs to be parsed, see {@link RevWalk#parseHeaders(RevObject)} and
+ * {@link RevWalk#parseBody(RevObject)}.
+ * <p>
+ * As an alternative, use {@link RevWalk#peel(RevObject)} and pass this
+ * {@link RevTag} to peel it until the first non-tag object.
*
- * @return object this tag refers to.
+ * @return object this tag refers to (only looked up, not parsed)
*/
public final RevObject getObject() {
return object;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefSpec.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefSpec.java
index 53a7b02be3..9b38b29336 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefSpec.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefSpec.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
+ * Copyright (C) 2008, 2013 Shawn O. Pearce <spearce@spearce.org>
* and other copyright owners as documented in the project's IP log.
*
* This program and the accompanying materials are made available
@@ -106,13 +106,13 @@ public class RefSpec implements Serializable {
* <p>
* Specifications are typically one of the following forms:
* <ul>
- * <li><code>refs/head/master</code></li>
- * <li><code>refs/head/master:refs/remotes/origin/master</code></li>
- * <li><code>refs/head/*:refs/remotes/origin/*</code></li>
- * <li><code>+refs/head/master</code></li>
- * <li><code>+refs/head/master:refs/remotes/origin/master</code></li>
- * <li><code>+refs/head/*:refs/remotes/origin/*</code></li>
- * <li><code>:refs/head/master</code></li>
+ * <li><code>refs/heads/master</code></li>
+ * <li><code>refs/heads/master:refs/remotes/origin/master</code></li>
+ * <li><code>refs/heads/*:refs/remotes/origin/*</code></li>
+ * <li><code>+refs/heads/master</code></li>
+ * <li><code>+refs/heads/master:refs/remotes/origin/master</code></li>
+ * <li><code>+refs/heads/*:refs/remotes/origin/*</code></li>
+ * <li><code>:refs/heads/master</code></li>
* </ul>
*
* @param spec
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/AbstractTreeIterator.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/AbstractTreeIterator.java
index 4cf79c0a27..2dd3c3aa14 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/AbstractTreeIterator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/AbstractTreeIterator.java
@@ -425,7 +425,14 @@ public abstract class AbstractTreeIterator {
return TreeWalk.pathOf(this);
}
- /** @return the internal buffer holding the current path. */
+ /**
+ * Get the current entry path buffer.
+ * <p>
+ * Note that the returned byte[] has to be used together with
+ * {@link #getEntryPathLength()} (only use bytes up to this length).
+ *
+ * @return the internal buffer holding the current path.
+ */
public byte[] getEntryPathBuffer() {
return path;
}