You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

DepthGenerator.java 5.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /*
  2. * Copyright (C) 2010, Garmin International
  3. * Copyright (C) 2010, Matt Fischer <matt.fischer@garmin.com>
  4. * and other copyright owners as documented in the project's IP log.
  5. *
  6. * This program and the accompanying materials are made available
  7. * under the terms of the Eclipse Distribution License v1.0 which
  8. * accompanies this distribution, is reproduced below, and is
  9. * available at http://www.eclipse.org/org/documents/edl-v10.php
  10. *
  11. * All rights reserved.
  12. *
  13. * Redistribution and use in source and binary forms, with or
  14. * without modification, are permitted provided that the following
  15. * conditions are met:
  16. *
  17. * - Redistributions of source code must retain the above copyright
  18. * notice, this list of conditions and the following disclaimer.
  19. *
  20. * - Redistributions in binary form must reproduce the above
  21. * copyright notice, this list of conditions and the following
  22. * disclaimer in the documentation and/or other materials provided
  23. * with the distribution.
  24. *
  25. * - Neither the name of the Eclipse Foundation, Inc. nor the
  26. * names of its contributors may be used to endorse or promote
  27. * products derived from this software without specific prior
  28. * written permission.
  29. *
  30. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  31. * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  32. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  33. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  34. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  35. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  36. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  37. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  38. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  39. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  40. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  41. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  42. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  43. */
  44. package org.eclipse.jgit.revwalk;
  45. import java.io.IOException;
  46. import org.eclipse.jgit.errors.IncorrectObjectTypeException;
  47. import org.eclipse.jgit.errors.MissingObjectException;
  48. /**
  49. * Only produce commits which are below a specified depth.
  50. *
  51. * @see DepthWalk
  52. */
  53. class DepthGenerator extends Generator {
  54. private final FIFORevQueue pending;
  55. private final int depth;
  56. private final RevWalk walk;
  57. /**
  58. * Commits which used to be shallow in the client, but which are
  59. * being extended as part of this fetch. These commits should be
  60. * returned to the caller as UNINTERESTING so that their blobs/trees
  61. * can be marked appropriately in the pack writer.
  62. */
  63. private final RevFlag UNSHALLOW;
  64. /**
  65. * Commits which the normal framework has marked as UNINTERESTING,
  66. * but which we now care about again. This happens if a client is
  67. * extending a shallow checkout to become deeper--the new commits at
  68. * the bottom of the graph need to be sent, even though they are
  69. * below other commits which the client already has.
  70. */
  71. private final RevFlag REINTERESTING;
  72. /**
  73. * @param w
  74. * @param s Parent generator
  75. * @throws MissingObjectException
  76. * @throws IncorrectObjectTypeException
  77. * @throws IOException
  78. */
  79. DepthGenerator(DepthWalk w, Generator s) throws MissingObjectException,
  80. IncorrectObjectTypeException, IOException {
  81. pending = new FIFORevQueue();
  82. walk = (RevWalk)w;
  83. this.depth = w.getDepth();
  84. this.UNSHALLOW = w.getUnshallowFlag();
  85. this.REINTERESTING = w.getReinterestingFlag();
  86. s.shareFreeList(pending);
  87. // Begin by sucking out all of the source's commits, and
  88. // adding them to the pending queue
  89. for (;;) {
  90. RevCommit c = s.next();
  91. if (c == null)
  92. break;
  93. if (((DepthWalk.Commit) c).getDepth() == 0)
  94. pending.add(c);
  95. }
  96. }
  97. @Override
  98. int outputType() {
  99. return pending.outputType() | HAS_UNINTERESTING;
  100. }
  101. @Override
  102. void shareFreeList(final BlockRevQueue q) {
  103. pending.shareFreeList(q);
  104. }
  105. @Override
  106. RevCommit next() throws MissingObjectException,
  107. IncorrectObjectTypeException, IOException {
  108. // Perform a breadth-first descent into the commit graph,
  109. // marking depths as we go. This means that if a commit is
  110. // reachable by more than one route, we are guaranteed to
  111. // arrive by the shortest route first.
  112. for (;;) {
  113. final DepthWalk.Commit c = (DepthWalk.Commit) pending.next();
  114. if (c == null)
  115. return null;
  116. if ((c.flags & RevWalk.PARSED) == 0)
  117. c.parseHeaders(walk);
  118. int newDepth = c.depth + 1;
  119. for (final RevCommit p : c.parents) {
  120. DepthWalk.Commit dp = (DepthWalk.Commit) p;
  121. // If no depth has been assigned to this commit, assign
  122. // it now. Since we arrive by the shortest route first,
  123. // this depth is guaranteed to be the smallest value that
  124. // any path could produce.
  125. if (dp.depth == -1) {
  126. dp.depth = newDepth;
  127. // If the parent is not too deep, add it to the queue
  128. // so that we can produce it later
  129. if (newDepth <= depth)
  130. pending.add(p);
  131. }
  132. // If the current commit has become unshallowed, everything
  133. // below us is new to the client. Mark its parent as
  134. // re-interesting, and carry that flag downward to all
  135. // of its ancestors.
  136. if(c.has(UNSHALLOW) || c.has(REINTERESTING)) {
  137. p.add(REINTERESTING);
  138. p.flags &= ~RevWalk.UNINTERESTING;
  139. }
  140. }
  141. // Produce all commits less than the depth cutoff
  142. boolean produce = c.depth <= depth;
  143. // Unshallow commits are uninteresting, but still need to be sent
  144. // up to the PackWriter so that it will exclude objects correctly.
  145. // All other uninteresting commits should be omitted.
  146. if ((c.flags & RevWalk.UNINTERESTING) != 0 && !c.has(UNSHALLOW))
  147. produce = false;
  148. if (produce)
  149. return c;
  150. }
  151. }
  152. }