1 /* 2 * Copyright (C) 2008-2009, Google Inc. 3 * Copyright (C) 2009, Robin Rosenberg <robin.rosenberg@dewire.com> 4 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others 5 * 6 * This program and the accompanying materials are made available under the 7 * terms of the Eclipse Distribution License v. 1.0 which is available at 8 * https://www.eclipse.org/org/documents/edl-v10.php. 9 * 10 * SPDX-License-Identifier: BSD-3-Clause 11 */ 12 13 package org.eclipse.jgit.dircache; 14 15 import java.io.IOException; 16 17 import org.eclipse.jgit.errors.CorruptObjectException; 18 import org.eclipse.jgit.errors.IncorrectObjectTypeException; 19 import org.eclipse.jgit.lib.Constants; 20 import org.eclipse.jgit.lib.ObjectReader; 21 import org.eclipse.jgit.treewalk.AbstractTreeIterator; 22 23 /** 24 * Iterate and update a {@link org.eclipse.jgit.dircache.DirCache} as part of a 25 * <code>TreeWalk</code>. 26 * <p> 27 * Like {@link org.eclipse.jgit.dircache.DirCacheIterator} this iterator allows 28 * a DirCache to be used in parallel with other sorts of iterators in a 29 * TreeWalk. However any entry which appears in the source DirCache and which is 30 * skipped by the TreeFilter is automatically copied into 31 * {@link org.eclipse.jgit.dircache.DirCacheBuilder}, thus retaining it in the 32 * newly updated index. 33 * <p> 34 * This iterator is suitable for update processes, or even a simple delete 35 * algorithm. For example deleting a path: 36 * 37 * <pre> 38 * final DirCache dirc = db.lockDirCache(); 39 * final DirCacheBuilder edit = dirc.builder(); 40 * 41 * final TreeWalk walk = new TreeWalk(db); 42 * walk.reset(); 43 * walk.setRecursive(true); 44 * walk.setFilter(PathFilter.create("name/to/remove")); 45 * walk.addTree(new DirCacheBuildIterator(edit)); 46 * 47 * while (walk.next()) 48 * ; // do nothing on a match as we want to remove matches 49 * edit.commit(); 50 * </pre> 51 */ 52 public class DirCacheBuildIterator extends DirCacheIterator { 53 private final DirCacheBuilder builder; 54 55 /** 56 * Create a new iterator for an already loaded DirCache instance. 57 * <p> 58 * The iterator implementation may copy part of the cache's data during 59 * construction, so the cache must be read in prior to creating the 60 * iterator. 61 * 62 * @param dcb 63 * the cache builder for the cache to walk. The cache must be 64 * already loaded into memory. 65 */ 66 public DirCacheBuildIterator(DirCacheBuilder dcb) { 67 super(dcb.getDirCache()); 68 builder = dcb; 69 } 70 71 DirCacheBuildIterator(final DirCacheBuildIterator p, 72 final DirCacheTree dct) { 73 super(p, dct); 74 builder = p.builder; 75 } 76 77 /** {@inheritDoc} */ 78 @Override 79 public AbstractTreeIterator createSubtreeIterator(ObjectReader reader) 80 throws IncorrectObjectTypeException, IOException { 81 if (currentSubtree == null) 82 throw new IncorrectObjectTypeException(getEntryObjectId(), 83 Constants.TYPE_TREE); 84 return new DirCacheBuildIterator(this, currentSubtree); 85 } 86 87 /** {@inheritDoc} */ 88 @Override 89 public void skip() throws CorruptObjectException { 90 if (currentSubtree != null) 91 builder.keep(ptr, currentSubtree.getEntrySpan()); 92 else 93 builder.keep(ptr, 1); 94 next(1); 95 } 96 97 /** {@inheritDoc} */ 98 @Override 99 public void stopWalk() { 100 final int cur = ptr; 101 final int cnt = cache.getEntryCount(); 102 if (cur < cnt) 103 builder.keep(cur, cnt - cur); 104 } 105 106 /** {@inheritDoc} */ 107 @Override 108 protected boolean needsStopWalk() { 109 return ptr < cache.getEntryCount(); 110 } 111 }