DepthWalk.java

  1. /*
  2.  * Copyright (C) 2010, Garmin International
  3.  * Copyright (C) 2010, Matt Fischer <matt.fischer@garmin.com> and others
  4.  *
  5.  * This program and the accompanying materials are made available under the
  6.  * terms of the Eclipse Distribution License v. 1.0 which is available at
  7.  * https://www.eclipse.org/org/documents/edl-v10.php.
  8.  *
  9.  * SPDX-License-Identifier: BSD-3-Clause
  10.  */

  11. package org.eclipse.jgit.revwalk;

  12. import java.io.IOException;
  13. import java.util.Collections;
  14. import java.util.List;
  15. import java.util.Objects;

  16. import org.eclipse.jgit.errors.IncorrectObjectTypeException;
  17. import org.eclipse.jgit.errors.MissingObjectException;
  18. import org.eclipse.jgit.lib.AnyObjectId;
  19. import org.eclipse.jgit.lib.ObjectId;
  20. import org.eclipse.jgit.lib.ObjectReader;
  21. import org.eclipse.jgit.lib.Repository;

  22. /**
  23.  * Interface for revision walkers that perform depth filtering.
  24.  */
  25. public interface DepthWalk {
  26.     /**
  27.      * Get depth to filter to.
  28.      *
  29.      * @return Depth to filter to.
  30.      */
  31.     int getDepth();

  32.     /**
  33.      * @return the deepen-since value; if not 0, this walk only returns commits
  34.      *         whose commit time is at or after this limit
  35.      * @since 5.2
  36.      */
  37.     default int getDeepenSince() {
  38.         return 0;
  39.     }

  40.     /**
  41.      * @return the objects specified by the client using --shallow-exclude
  42.      * @since 5.2
  43.      */
  44.     default List<ObjectId> getDeepenNots() {
  45.         return Collections.emptyList();
  46.     }

  47.     /** @return flag marking commits that should become unshallow. */
  48.     /**
  49.      * Get flag marking commits that should become unshallow.
  50.      *
  51.      * @return flag marking commits that should become unshallow.
  52.      */
  53.     RevFlag getUnshallowFlag();

  54.     /**
  55.      * Get flag marking commits that are interesting again.
  56.      *
  57.      * @return flag marking commits that are interesting again.
  58.      */
  59.     RevFlag getReinterestingFlag();

  60.     /**
  61.      * @return flag marking commits that are to be excluded because of --shallow-exclude
  62.      * @since 5.2
  63.      */
  64.     RevFlag getDeepenNotFlag();

  65.     /** RevCommit with a depth (in commits) from a root. */
  66.     public static class Commit extends RevCommit {
  67.         /** Depth of this commit in the graph, via shortest path. */
  68.         int depth;

  69.         boolean isBoundary;

  70.         /**
  71.          * True if this commit was excluded due to a shallow fetch
  72.          * setting. All its children are thus boundary commits.
  73.          */
  74.         boolean makesChildBoundary;

  75.         /** @return depth of this commit, as found by the shortest path. */
  76.         public int getDepth() {
  77.             return depth;
  78.         }

  79.         /**
  80.          * @return true if at least one of this commit's parents was excluded
  81.          *         due to a shallow fetch setting, false otherwise
  82.          * @since 5.2
  83.          */
  84.         public boolean isBoundary() {
  85.             return isBoundary;
  86.         }

  87.         /**
  88.          * Initialize a new commit.
  89.          *
  90.          * @param id
  91.          *            object name for the commit.
  92.          */
  93.         protected Commit(AnyObjectId id) {
  94.             super(id);
  95.             depth = -1;
  96.         }
  97.     }

  98.     /** Subclass of RevWalk that performs depth filtering. */
  99.     public class RevWalk extends org.eclipse.jgit.revwalk.RevWalk implements DepthWalk {
  100.         private final int depth;

  101.         private int deepenSince;

  102.         private List<ObjectId> deepenNots;

  103.         private final RevFlag UNSHALLOW;

  104.         private final RevFlag REINTERESTING;

  105.         private final RevFlag DEEPEN_NOT;

  106.         /**
  107.          * @param repo Repository to walk
  108.          * @param depth Maximum depth to return
  109.          */
  110.         public RevWalk(Repository repo, int depth) {
  111.             super(repo);

  112.             this.depth = depth;
  113.             this.deepenNots = Collections.emptyList();
  114.             this.UNSHALLOW = newFlag("UNSHALLOW"); //$NON-NLS-1$
  115.             this.REINTERESTING = newFlag("REINTERESTING"); //$NON-NLS-1$
  116.             this.DEEPEN_NOT = newFlag("DEEPEN_NOT"); //$NON-NLS-1$
  117.         }

  118.         /**
  119.          * @param or ObjectReader to use
  120.          * @param depth Maximum depth to return
  121.          */
  122.         public RevWalk(ObjectReader or, int depth) {
  123.             super(or);

  124.             this.depth = depth;
  125.             this.deepenNots = Collections.emptyList();
  126.             this.UNSHALLOW = newFlag("UNSHALLOW"); //$NON-NLS-1$
  127.             this.REINTERESTING = newFlag("REINTERESTING"); //$NON-NLS-1$
  128.             this.DEEPEN_NOT = newFlag("DEEPEN_NOT"); //$NON-NLS-1$
  129.         }

  130.         /**
  131.          * Mark a root commit (i.e., one whose depth should be considered 0.)
  132.          *
  133.          * @param c
  134.          *            Commit to mark
  135.          * @throws IOException
  136.          * @throws IncorrectObjectTypeException
  137.          * @throws MissingObjectException
  138.          */
  139.         public void markRoot(RevCommit c) throws MissingObjectException,
  140.                 IncorrectObjectTypeException, IOException {
  141.             if (c instanceof Commit)
  142.                 ((Commit) c).depth = 0;
  143.             super.markStart(c);
  144.         }

  145.         @Override
  146.         protected RevCommit createCommit(AnyObjectId id) {
  147.             return new Commit(id);
  148.         }

  149.         @Override
  150.         public int getDepth() {
  151.             return depth;
  152.         }

  153.         @Override
  154.         public int getDeepenSince() {
  155.             return deepenSince;
  156.         }

  157.         /**
  158.          * Sets the deepen-since value.
  159.          *
  160.          * @param limit
  161.          *            new deepen-since value
  162.          * @since 5.2
  163.          */
  164.         public void setDeepenSince(int limit) {
  165.             deepenSince = limit;
  166.         }

  167.         @Override
  168.         public List<ObjectId> getDeepenNots() {
  169.             return deepenNots;
  170.         }

  171.         /**
  172.          * Mark objects that the client specified using
  173.          * --shallow-exclude. Objects that are not commits have no
  174.          * effect.
  175.          *
  176.          * @param deepenNots specified objects
  177.          * @since 5.2
  178.          */
  179.         public void setDeepenNots(List<ObjectId> deepenNots) {
  180.             this.deepenNots = Objects.requireNonNull(deepenNots);
  181.         }

  182.         @Override
  183.         public RevFlag getUnshallowFlag() {
  184.             return UNSHALLOW;
  185.         }

  186.         @Override
  187.         public RevFlag getReinterestingFlag() {
  188.             return REINTERESTING;
  189.         }

  190.         @Override
  191.         public RevFlag getDeepenNotFlag() {
  192.             return DEEPEN_NOT;
  193.         }

  194.         /**
  195.          * @since 4.5
  196.          */
  197.         @Override
  198.         public ObjectWalk toObjectWalkWithSameObjects() {
  199.             ObjectWalk ow = new ObjectWalk(reader, depth);
  200.             ow.deepenSince = deepenSince;
  201.             ow.deepenNots = deepenNots;
  202.             ow.objects = objects;
  203.             ow.freeFlags = freeFlags;
  204.             return ow;
  205.         }
  206.     }

  207.     /** Subclass of ObjectWalk that performs depth filtering. */
  208.     public class ObjectWalk extends org.eclipse.jgit.revwalk.ObjectWalk implements DepthWalk {
  209.         private final int depth;

  210.         private int deepenSince;

  211.         private List<ObjectId> deepenNots;

  212.         private final RevFlag UNSHALLOW;

  213.         private final RevFlag REINTERESTING;

  214.         private final RevFlag DEEPEN_NOT;

  215.         /**
  216.          * @param repo Repository to walk
  217.          * @param depth Maximum depth to return
  218.          */
  219.         public ObjectWalk(Repository repo, int depth) {
  220.             super(repo);

  221.             this.depth = depth;
  222.             this.deepenNots = Collections.emptyList();
  223.             this.UNSHALLOW = newFlag("UNSHALLOW"); //$NON-NLS-1$
  224.             this.REINTERESTING = newFlag("REINTERESTING"); //$NON-NLS-1$
  225.             this.DEEPEN_NOT = newFlag("DEEPEN_NOT"); //$NON-NLS-1$
  226.         }

  227.         /**
  228.          * @param or Object Reader
  229.          * @param depth Maximum depth to return
  230.          */
  231.         public ObjectWalk(ObjectReader or, int depth) {
  232.             super(or);

  233.             this.depth = depth;
  234.             this.deepenNots = Collections.emptyList();
  235.             this.UNSHALLOW = newFlag("UNSHALLOW"); //$NON-NLS-1$
  236.             this.REINTERESTING = newFlag("REINTERESTING"); //$NON-NLS-1$
  237.             this.DEEPEN_NOT = newFlag("DEEPEN_NOT"); //$NON-NLS-1$
  238.         }

  239.         /**
  240.          * Mark a root commit (i.e., one whose depth should be considered 0.)
  241.          *
  242.          * @param o
  243.          *            Commit to mark
  244.          * @throws IOException
  245.          * @throws IncorrectObjectTypeException
  246.          * @throws MissingObjectException
  247.          */
  248.         public void markRoot(RevObject o) throws MissingObjectException,
  249.                 IncorrectObjectTypeException, IOException {
  250.             RevObject c = o;
  251.             while (c instanceof RevTag) {
  252.                 c = ((RevTag) c).getObject();
  253.                 parseHeaders(c);
  254.             }
  255.             if (c instanceof Commit)
  256.                 ((Commit) c).depth = 0;
  257.             super.markStart(o);
  258.         }

  259.         /**
  260.          * Mark an element which used to be shallow in the client, but which
  261.          * should now be considered a full commit. Any ancestors of this commit
  262.          * should be included in the walk, even if they are the ancestor of an
  263.          * uninteresting commit.
  264.          *
  265.          * @param c
  266.          *            Commit to mark
  267.          * @throws MissingObjectException
  268.          * @throws IncorrectObjectTypeException
  269.          * @throws IOException
  270.          */
  271.         public void markUnshallow(RevObject c) throws MissingObjectException,
  272.                 IncorrectObjectTypeException, IOException {
  273.             if (c instanceof RevCommit)
  274.                 c.add(UNSHALLOW);
  275.             super.markStart(c);
  276.         }

  277.         @Override
  278.         protected RevCommit createCommit(AnyObjectId id) {
  279.             return new Commit(id);
  280.         }

  281.         @Override
  282.         public int getDepth() {
  283.             return depth;
  284.         }

  285.         @Override
  286.         public int getDeepenSince() {
  287.             return deepenSince;
  288.         }

  289.         @Override
  290.         public List<ObjectId> getDeepenNots() {
  291.             return deepenNots;
  292.         }

  293.         @Override
  294.         public RevFlag getUnshallowFlag() {
  295.             return UNSHALLOW;
  296.         }

  297.         @Override
  298.         public RevFlag getReinterestingFlag() {
  299.             return REINTERESTING;
  300.         }

  301.         @Override
  302.         public RevFlag getDeepenNotFlag() {
  303.             return DEEPEN_NOT;
  304.         }
  305.     }
  306. }