RefRename.java

  1. /*
  2.  * Copyright (C) 2009-2010, Google Inc.
  3.  * Copyright (C) 2009, Robin Rosenberg
  4.  * Copyright (C) 2009, Robin Rosenberg <robin.rosenberg@dewire.com>
  5.  * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
  6.  *
  7.  * This program and the accompanying materials are made available under the
  8.  * terms of the Eclipse Distribution License v. 1.0 which is available at
  9.  * https://www.eclipse.org/org/documents/edl-v10.php.
  10.  *
  11.  * SPDX-License-Identifier: BSD-3-Clause
  12.  */

  13. package org.eclipse.jgit.lib;

  14. import java.io.IOException;

  15. import org.eclipse.jgit.lib.RefUpdate.Result;

  16. /**
  17.  * A RefUpdate combination for renaming a reference.
  18.  * <p>
  19.  * If the source reference is currently pointed to by {@code HEAD}, then the
  20.  * HEAD symbolic reference is updated to point to the new destination.
  21.  */
  22. public abstract class RefRename {
  23.     /** Update operation to read and delete the source reference. */
  24.     protected final RefUpdate source;

  25.     /** Update operation to create/overwrite the destination reference. */
  26.     protected final RefUpdate destination;

  27.     private Result result = Result.NOT_ATTEMPTED;

  28.     /**
  29.      * Initialize a new rename operation.
  30.      *
  31.      * @param src
  32.      *            operation to read and delete the source.
  33.      * @param dst
  34.      *            operation to create (or overwrite) the destination.
  35.      */
  36.     protected RefRename(RefUpdate src, RefUpdate dst) {
  37.         source = src;
  38.         destination = dst;

  39.         String cmd = ""; //$NON-NLS-1$
  40.         if (source.getName().startsWith(Constants.R_HEADS)
  41.                 && destination.getName().startsWith(Constants.R_HEADS))
  42.             cmd = "Branch: "; //$NON-NLS-1$
  43.         setRefLogMessage(cmd + "renamed " //$NON-NLS-1$
  44.                 + Repository.shortenRefName(source.getName()) + " to " //$NON-NLS-1$
  45.                 + Repository.shortenRefName(destination.getName()));
  46.     }

  47.     /**
  48.      * Get identity of the user making the change in the reflog.
  49.      *
  50.      * @return identity of the user making the change in the reflog.
  51.      */
  52.     public PersonIdent getRefLogIdent() {
  53.         return destination.getRefLogIdent();
  54.     }

  55.     /**
  56.      * Set the identity of the user appearing in the reflog.
  57.      * <p>
  58.      * The timestamp portion of the identity is ignored. A new identity with the
  59.      * current timestamp will be created automatically when the rename occurs
  60.      * and the log record is written.
  61.      *
  62.      * @param pi
  63.      *            identity of the user. If null the identity will be
  64.      *            automatically determined based on the repository
  65.      *            configuration.
  66.      */
  67.     public void setRefLogIdent(PersonIdent pi) {
  68.         destination.setRefLogIdent(pi);
  69.     }

  70.     /**
  71.      * Get the message to include in the reflog.
  72.      *
  73.      * @return message the caller wants to include in the reflog; null if the
  74.      *         rename should not be logged.
  75.      */
  76.     public String getRefLogMessage() {
  77.         return destination.getRefLogMessage();
  78.     }

  79.     /**
  80.      * Set the message to include in the reflog.
  81.      *
  82.      * @param msg
  83.      *            the message to describe this change.
  84.      */
  85.     public void setRefLogMessage(String msg) {
  86.         if (msg == null)
  87.             disableRefLog();
  88.         else
  89.             destination.setRefLogMessage(msg, false);
  90.     }

  91.     /**
  92.      * Don't record this rename in the ref's associated reflog.
  93.      */
  94.     public void disableRefLog() {
  95.         destination.setRefLogMessage("", false); //$NON-NLS-1$
  96.     }

  97.     /**
  98.      * Get result of rename operation
  99.      *
  100.      * @return result of rename operation
  101.      */
  102.     public Result getResult() {
  103.         return result;
  104.     }

  105.     /**
  106.      * Rename
  107.      *
  108.      * @return the result of the new ref update
  109.      * @throws java.io.IOException
  110.      */
  111.     public Result rename() throws IOException {
  112.         try {
  113.             result = doRename();
  114.             return result;
  115.         } catch (IOException err) {
  116.             result = Result.IO_FAILURE;
  117.             throw err;
  118.         }
  119.     }

  120.     /**
  121.      * Do the actual rename
  122.      *
  123.      * @return the result of the rename operation.
  124.      * @throws java.io.IOException
  125.      */
  126.     protected abstract Result doRename() throws IOException;

  127.     /**
  128.      * Whether the {@code Constants#HEAD} reference needs to be linked to the
  129.      * new destination name.
  130.      *
  131.      * @return true if the {@code Constants#HEAD} reference needs to be linked
  132.      *         to the new destination name.
  133.      * @throws java.io.IOException
  134.      *             the current value of {@code HEAD} cannot be read.
  135.      */
  136.     protected boolean needToUpdateHEAD() throws IOException {
  137.         Ref head = source.getRefDatabase().exactRef(Constants.HEAD);
  138.         if (head != null && head.isSymbolic()) {
  139.             head = head.getTarget();
  140.             return head.getName().equals(source.getName());
  141.         }
  142.         return false;
  143.     }
  144. }