private DirCache createTemporaryIndex()

in org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java [413:564]


	private DirCache createTemporaryIndex(ObjectId headId, DirCache index,
			RevWalk rw)
			throws IOException {
		ObjectInserter inserter = null;

		// get DirCacheBuilder for existing index
		DirCacheBuilder existingBuilder = index.builder();

		// get DirCacheBuilder for newly created in-core index to build a
		// temporary index for this commit
		DirCache inCoreIndex = DirCache.newInCore();
		DirCacheBuilder tempBuilder = inCoreIndex.builder();

		onlyProcessed = new boolean[only.size()];
		boolean emptyCommit = true;

		try (TreeWalk treeWalk = new TreeWalk(repo)) {
			treeWalk.setOperationType(OperationType.CHECKIN_OP);
			int dcIdx = treeWalk
					.addTree(new DirCacheBuildIterator(existingBuilder));
			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));
			treeWalk.setRecursive(true);

			String lastAddedFile = null;
			while (treeWalk.next()) {
				String path = treeWalk.getPathString();
				// check if current entry's path matches a specified path
				int pos = lookupOnly(path);

				CanonicalTreeParser hTree = null;
				if (hIdx != -1)
					hTree = treeWalk.getTree(hIdx, CanonicalTreeParser.class);

				DirCacheIterator dcTree = treeWalk.getTree(dcIdx,
						DirCacheIterator.class);

				if (pos >= 0) {
					// include entry in commit

					FileTreeIterator fTree = treeWalk.getTree(fIdx,
							FileTreeIterator.class);

					// check if entry refers to a tracked file
					boolean tracked = dcTree != null || hTree != null;
					if (!tracked)
						continue;

					// for an unmerged path, DirCacheBuildIterator will yield 3
					// entries, we only want to add one
					if (path.equals(lastAddedFile))
						continue;

					lastAddedFile = path;

					if (fTree != null) {
						// create a new DirCacheEntry with data retrieved from
						// disk
						final DirCacheEntry dcEntry = new DirCacheEntry(path);
						long entryLength = fTree.getEntryLength();
						dcEntry.setLength(entryLength);
						dcEntry.setLastModified(fTree.getEntryLastModifiedInstant());
						dcEntry.setFileMode(fTree.getIndexFileMode(dcTree));

						boolean objectExists = (dcTree != null
								&& fTree.idEqual(dcTree))
								|| (hTree != null && fTree.idEqual(hTree));
						if (objectExists) {
							dcEntry.setObjectId(fTree.getEntryObjectId());
						} else {
							if (FileMode.GITLINK.equals(dcEntry.getFileMode()))
								dcEntry.setObjectId(fTree.getEntryObjectId());
							else {
								// insert object
								if (inserter == null)
									inserter = repo.newObjectInserter();
								long contentLength = fTree
										.getEntryContentLength();
								try (InputStream inputStream = fTree
										.openEntryStream()) {
									dcEntry.setObjectId(inserter.insert(
											Constants.OBJ_BLOB, contentLength,
											inputStream));
								}
							}
						}

						// add to existing index
						existingBuilder.add(dcEntry);
						// add to temporary in-core index
						tempBuilder.add(dcEntry);

						if (emptyCommit
								&& (hTree == null || !hTree.idEqual(fTree)
										|| hTree.getEntryRawMode() != fTree
												.getEntryRawMode()))
							// this is a change
							emptyCommit = false;
					} else {
						// if no file exists on disk, neither add it to
						// index nor to temporary in-core index

						if (emptyCommit && hTree != null)
							// this is a change
							emptyCommit = false;
					}

					// keep track of processed path
					onlyProcessed[pos] = true;
				} else {
					// add entries from HEAD for all other paths
					if (hTree != null) {
						// create a new DirCacheEntry with data retrieved from
						// HEAD
						final DirCacheEntry dcEntry = new DirCacheEntry(path);
						dcEntry.setObjectId(hTree.getEntryObjectId());
						dcEntry.setFileMode(hTree.getEntryFileMode());

						// add to temporary in-core index
						tempBuilder.add(dcEntry);
					}

					// preserve existing entry in index
					if (dcTree != null)
						existingBuilder.add(dcTree.getDirCacheEntry());
				}
			}
		}

		// there must be no unprocessed paths left at this point; otherwise an
		// untracked or unknown path has been specified
		for (int i = 0; i < onlyProcessed.length; i++)
			if (!onlyProcessed[i])
				throw new JGitInternalException(MessageFormat.format(
						JGitText.get().entryNotFoundByPath, only.get(i)));

		// there must be at least one change
		if (emptyCommit && !allowEmpty.booleanValue())
			// Would like to throw a EmptyCommitException. But this would break the API
			// TODO(ch): Change this in the next release
			throw new JGitInternalException(JGitText.get().emptyCommit);

		// update index
		existingBuilder.commit();
		// finish temporary in-core index used for this commit
		tempBuilder.finish();
		return inCoreIndex;
	}