|
|
|
@ -43,6 +43,9 @@
|
|
|
|
|
*/ |
|
|
|
|
package org.eclipse.jgit.api; |
|
|
|
|
|
|
|
|
|
import static org.eclipse.jgit.lib.Constants.OBJ_BLOB; |
|
|
|
|
import static org.eclipse.jgit.lib.FileMode.GITLINK; |
|
|
|
|
|
|
|
|
|
import java.io.IOException; |
|
|
|
|
import java.io.InputStream; |
|
|
|
|
import java.util.Collection; |
|
|
|
@ -58,8 +61,8 @@ import org.eclipse.jgit.dircache.DirCacheBuilder;
|
|
|
|
|
import org.eclipse.jgit.dircache.DirCacheEntry; |
|
|
|
|
import org.eclipse.jgit.dircache.DirCacheIterator; |
|
|
|
|
import org.eclipse.jgit.internal.JGitText; |
|
|
|
|
import org.eclipse.jgit.lib.Constants; |
|
|
|
|
import org.eclipse.jgit.lib.FileMode; |
|
|
|
|
import org.eclipse.jgit.lib.ObjectId; |
|
|
|
|
import org.eclipse.jgit.lib.ObjectInserter; |
|
|
|
|
import org.eclipse.jgit.lib.Repository; |
|
|
|
|
import org.eclipse.jgit.treewalk.FileTreeIterator; |
|
|
|
@ -135,15 +138,12 @@ public class AddCommand extends GitCommand<DirCache> {
|
|
|
|
|
throw new NoFilepatternException(JGitText.get().atLeastOnePatternIsRequired); |
|
|
|
|
checkCallable(); |
|
|
|
|
DirCache dc = null; |
|
|
|
|
boolean addAll = false; |
|
|
|
|
if (filepatterns.contains(".")) //$NON-NLS-1$
|
|
|
|
|
addAll = true; |
|
|
|
|
boolean addAll = filepatterns.contains("."); //$NON-NLS-1$
|
|
|
|
|
|
|
|
|
|
try (ObjectInserter inserter = repo.newObjectInserter(); |
|
|
|
|
final TreeWalk tw = new TreeWalk(repo)) { |
|
|
|
|
tw.setOperationType(OperationType.CHECKIN_OP); |
|
|
|
|
dc = repo.lockDirCache(); |
|
|
|
|
DirCacheIterator c; |
|
|
|
|
|
|
|
|
|
DirCacheBuilder builder = dc.builder(); |
|
|
|
|
tw.addTree(new DirCacheBuildIterator(builder)); |
|
|
|
@ -158,55 +158,60 @@ public class AddCommand extends GitCommand<DirCache> {
|
|
|
|
|
String lastAddedFile = null; |
|
|
|
|
|
|
|
|
|
while (tw.next()) { |
|
|
|
|
String path = tw.getPathString(); |
|
|
|
|
|
|
|
|
|
DirCacheIterator c = tw.getTree(0, DirCacheIterator.class); |
|
|
|
|
WorkingTreeIterator f = tw.getTree(1, WorkingTreeIterator.class); |
|
|
|
|
if (tw.getTree(0, DirCacheIterator.class) == null && |
|
|
|
|
f != null && f.isEntryIgnored()) { |
|
|
|
|
if (c == null && f != null && f.isEntryIgnored()) { |
|
|
|
|
// file is not in index but is ignored, do nothing
|
|
|
|
|
continue; |
|
|
|
|
} else if (c == null && update) { |
|
|
|
|
// Only update of existing entries was requested.
|
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
// In case of an existing merge conflict the
|
|
|
|
|
// DirCacheBuildIterator iterates over all stages of
|
|
|
|
|
// this path, we however want to add only one
|
|
|
|
|
// new DirCacheEntry per path.
|
|
|
|
|
else if (!(path.equals(lastAddedFile))) { |
|
|
|
|
if (!(update && tw.getTree(0, DirCacheIterator.class) == null)) { |
|
|
|
|
c = tw.getTree(0, DirCacheIterator.class); |
|
|
|
|
if (f != null) { // the file exists
|
|
|
|
|
long sz = f.getEntryLength(); |
|
|
|
|
DirCacheEntry entry = new DirCacheEntry(path); |
|
|
|
|
if (c == null || c.getDirCacheEntry() == null |
|
|
|
|
|| !c.getDirCacheEntry().isAssumeValid()) { |
|
|
|
|
FileMode mode = f.getIndexFileMode(c); |
|
|
|
|
entry.setFileMode(mode); |
|
|
|
|
|
|
|
|
|
if (FileMode.GITLINK != mode) { |
|
|
|
|
entry.setLength(sz); |
|
|
|
|
entry.setLastModified(f |
|
|
|
|
.getEntryLastModified()); |
|
|
|
|
long contentSize = f |
|
|
|
|
.getEntryContentLength(); |
|
|
|
|
InputStream in = f.openEntryStream(); |
|
|
|
|
try { |
|
|
|
|
entry.setObjectId(inserter.insert( |
|
|
|
|
Constants.OBJ_BLOB, contentSize, in)); |
|
|
|
|
} finally { |
|
|
|
|
in.close(); |
|
|
|
|
} |
|
|
|
|
} else |
|
|
|
|
entry.setObjectId(f.getEntryObjectId()); |
|
|
|
|
builder.add(entry); |
|
|
|
|
lastAddedFile = path; |
|
|
|
|
} else { |
|
|
|
|
builder.add(c.getDirCacheEntry()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} else if (c != null |
|
|
|
|
&& (!update || FileMode.GITLINK == c |
|
|
|
|
.getEntryFileMode())) |
|
|
|
|
builder.add(c.getDirCacheEntry()); |
|
|
|
|
|
|
|
|
|
String path = tw.getPathString(); |
|
|
|
|
if (path.equals(lastAddedFile)) { |
|
|
|
|
// In case of an existing merge conflict the
|
|
|
|
|
// DirCacheBuildIterator iterates over all stages of
|
|
|
|
|
// this path, we however want to add only one
|
|
|
|
|
// new DirCacheEntry per path.
|
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (f == null) { // working tree file does not exist
|
|
|
|
|
if (c != null |
|
|
|
|
&& (!update || GITLINK == c.getEntryFileMode())) { |
|
|
|
|
builder.add(c.getDirCacheEntry()); |
|
|
|
|
} |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (c != null && c.getDirCacheEntry() != null |
|
|
|
|
&& c.getDirCacheEntry().isAssumeValid()) { |
|
|
|
|
// Index entry is marked assume valid. Even though
|
|
|
|
|
// the user specified the file to be added JGit does
|
|
|
|
|
// not consider the file for addition.
|
|
|
|
|
builder.add(c.getDirCacheEntry()); |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
long sz = f.getEntryLength(); |
|
|
|
|
DirCacheEntry entry = new DirCacheEntry(path); |
|
|
|
|
FileMode mode = f.getIndexFileMode(c); |
|
|
|
|
entry.setFileMode(mode); |
|
|
|
|
|
|
|
|
|
if (GITLINK != mode) { |
|
|
|
|
entry.setLength(sz); |
|
|
|
|
entry.setLastModified(f.getEntryLastModified()); |
|
|
|
|
long len = f.getEntryContentLength(); |
|
|
|
|
try (InputStream in = f.openEntryStream()) { |
|
|
|
|
ObjectId id = inserter.insert(OBJ_BLOB, len, in); |
|
|
|
|
entry.setObjectId(id); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
entry.setObjectId(f.getEntryObjectId()); |
|
|
|
|
} |
|
|
|
|
builder.add(entry); |
|
|
|
|
lastAddedFile = path; |
|
|
|
|
} |
|
|
|
|
inserter.flush(); |
|
|
|
|
builder.commit(); |
|
|
|
|