ThreeWayMerger.java

  1. /*
  2.  * Copyright (C) 2009, Google Inc.
  3.  * Copyright (C) 2012, Research In Motion Limited 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.merge;

  12. import java.io.IOException;

  13. import org.eclipse.jgit.errors.IncorrectObjectTypeException;
  14. import org.eclipse.jgit.errors.MissingObjectException;
  15. import org.eclipse.jgit.lib.AnyObjectId;
  16. import org.eclipse.jgit.lib.ObjectId;
  17. import org.eclipse.jgit.lib.ObjectInserter;
  18. import org.eclipse.jgit.lib.Repository;
  19. import org.eclipse.jgit.revwalk.RevCommit;
  20. import org.eclipse.jgit.revwalk.RevTree;
  21. import org.eclipse.jgit.treewalk.AbstractTreeIterator;
  22. import org.eclipse.jgit.treewalk.EmptyTreeIterator;

  23. /**
  24.  * A merge of 2 trees, using a common base ancestor tree.
  25.  */
  26. public abstract class ThreeWayMerger extends Merger {
  27.     private RevTree baseTree;

  28.     private ObjectId baseCommitId;

  29.     /**
  30.      * Create a new merge instance for a repository.
  31.      *
  32.      * @param local
  33.      *            the repository this merger will read and write data on.
  34.      */
  35.     protected ThreeWayMerger(Repository local) {
  36.         super(local);
  37.     }

  38.     /**
  39.      * Create a new merge instance for a repository.
  40.      *
  41.      * @param local
  42.      *            the repository this merger will read and write data on.
  43.      * @param inCore
  44.      *            perform the merge in core with no working folder involved
  45.      */
  46.     protected ThreeWayMerger(Repository local, boolean inCore) {
  47.         this(local);
  48.     }

  49.     /**
  50.      * Create a new in-core merge instance from an inserter.
  51.      *
  52.      * @param inserter
  53.      *            the inserter to write objects to.
  54.      * @since 4.8
  55.      */
  56.     protected ThreeWayMerger(ObjectInserter inserter) {
  57.         super(inserter);
  58.     }

  59.     /**
  60.      * Set the common ancestor tree.
  61.      *
  62.      * @param id
  63.      *            common base treeish; null to automatically compute the common
  64.      *            base from the input commits during
  65.      *            {@link #merge(AnyObjectId...)}.
  66.      * @throws org.eclipse.jgit.errors.IncorrectObjectTypeException
  67.      *             the object is not a treeish.
  68.      * @throws org.eclipse.jgit.errors.MissingObjectException
  69.      *             the object does not exist.
  70.      * @throws java.io.IOException
  71.      *             the object could not be read.
  72.      */
  73.     public void setBase(AnyObjectId id) throws MissingObjectException,
  74.             IncorrectObjectTypeException, IOException {
  75.         if (id != null) {
  76.             baseTree = walk.parseTree(id);
  77.         } else {
  78.             baseTree = null;
  79.         }
  80.     }

  81.     /** {@inheritDoc} */
  82.     @Override
  83.     public boolean merge(AnyObjectId... tips) throws IOException {
  84.         if (tips.length != 2)
  85.             return false;
  86.         return super.merge(tips);
  87.     }

  88.     /** {@inheritDoc} */
  89.     @Override
  90.     public ObjectId getBaseCommitId() {
  91.         return baseCommitId;
  92.     }

  93.     /**
  94.      * Create an iterator to walk the merge base.
  95.      *
  96.      * @return an iterator over the caller-specified merge base, or the natural
  97.      *         merge base of the two input commits.
  98.      * @throws java.io.IOException
  99.      */
  100.     protected AbstractTreeIterator mergeBase() throws IOException {
  101.         if (baseTree != null) {
  102.             return openTree(baseTree);
  103.         }
  104.         RevCommit baseCommit = (baseCommitId != null) ? walk
  105.                 .parseCommit(baseCommitId) : getBaseCommit(sourceCommits[0],
  106.                 sourceCommits[1]);
  107.         if (baseCommit == null) {
  108.             baseCommitId = null;
  109.             return new EmptyTreeIterator();
  110.         }
  111.         baseCommitId = baseCommit.toObjectId();
  112.         return openTree(baseCommit.getTree());
  113.     }
  114. }