BranchConfig.java

  1. /*
  2.  * Copyright (C) 2011, Robin Stocker <robin@nibor.org>
  3.  * Copyright (C) 2012, Matthias Sohn <matthias.sohn@sap.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.lib;

  12. import java.net.URISyntaxException;

  13. import org.eclipse.jgit.transport.RefSpec;
  14. import org.eclipse.jgit.transport.RemoteConfig;

  15. /**
  16.  * Branch section of a Git configuration file.
  17.  */
  18. public class BranchConfig {

  19.     /**
  20.      * Config values for branch.[name].rebase (and pull.rebase).
  21.      *
  22.      * @since 4.5
  23.      */
  24.     public enum BranchRebaseMode implements Config.ConfigEnum {

  25.         /** Value for rebasing */
  26.         REBASE("true"), //$NON-NLS-1$
  27.         /** Value for rebasing preserving local merge commits */
  28.         PRESERVE("preserve"), //$NON-NLS-1$
  29.         /** Value for rebasing interactively */
  30.         INTERACTIVE("interactive"), //$NON-NLS-1$
  31.         /** Value for not rebasing at all but merging */
  32.         NONE("false"); //$NON-NLS-1$

  33.         private final String configValue;

  34.         private BranchRebaseMode(String configValue) {
  35.             this.configValue = configValue;
  36.         }

  37.         @Override
  38.         public String toConfigValue() {
  39.             return configValue;
  40.         }

  41.         @Override
  42.         public boolean matchConfigValue(String s) {
  43.             return configValue.equals(s);
  44.         }
  45.     }

  46.     /**
  47.      * The value that means "local repository" for {@link #getRemote()}:
  48.      * {@value}
  49.      *
  50.      * @since 3.5
  51.      */
  52.     public static final String LOCAL_REPOSITORY = "."; //$NON-NLS-1$

  53.     private final Config config;
  54.     private final String branchName;

  55.     /**
  56.      * Create a new branch config, which will read configuration from config
  57.      * about specified branch.
  58.      *
  59.      * @param config
  60.      *            the config to read from
  61.      * @param branchName
  62.      *            the short branch name of the section to read
  63.      */
  64.     public BranchConfig(Config config, String branchName) {
  65.         this.config = config;
  66.         this.branchName = branchName;
  67.     }

  68.     /**
  69.      * Get the full tracking branch name
  70.      *
  71.      * @return the full tracking branch name or <code>null</code> if it could
  72.      *         not be determined
  73.      */
  74.     public String getTrackingBranch() {
  75.         String remote = getRemoteOrDefault();
  76.         String mergeRef = getMerge();
  77.         if (remote == null || mergeRef == null)
  78.             return null;

  79.         if (isRemoteLocal())
  80.             return mergeRef;

  81.         return findRemoteTrackingBranch(remote, mergeRef);
  82.     }

  83.     /**
  84.      * Get the full remote-tracking branch name
  85.      *
  86.      * @return the full remote-tracking branch name or {@code null} if it could
  87.      *         not be determined. If you also want local tracked branches use
  88.      *         {@link #getTrackingBranch()} instead.
  89.      */
  90.     public String getRemoteTrackingBranch() {
  91.         String remote = getRemoteOrDefault();
  92.         String mergeRef = getMerge();
  93.         if (remote == null || mergeRef == null)
  94.             return null;

  95.         return findRemoteTrackingBranch(remote, mergeRef);
  96.     }

  97.     /**
  98.      * Whether the "remote" setting points to the local repository (with
  99.      * {@value #LOCAL_REPOSITORY})
  100.      *
  101.      * @return {@code true} if the "remote" setting points to the local
  102.      *         repository (with {@value #LOCAL_REPOSITORY}), false otherwise
  103.      * @since 3.5
  104.      */
  105.     public boolean isRemoteLocal() {
  106.         return LOCAL_REPOSITORY.equals(getRemote());
  107.     }

  108.     /**
  109.      * Get the remote this branch is configured to fetch from/push to
  110.      *
  111.      * @return the remote this branch is configured to fetch from/push to, or
  112.      *         {@code null} if not defined
  113.      * @since 3.5
  114.      */
  115.     public String getRemote() {
  116.         return config.getString(ConfigConstants.CONFIG_BRANCH_SECTION,
  117.                 branchName, ConfigConstants.CONFIG_KEY_REMOTE);
  118.     }

  119.     /**
  120.      * Get the name of the upstream branch as it is called on the remote
  121.      *
  122.      * @return the name of the upstream branch as it is called on the remote, or
  123.      *         {@code null} if not defined
  124.      * @since 3.5
  125.      */
  126.     public String getMerge() {
  127.         return config.getString(ConfigConstants.CONFIG_BRANCH_SECTION,
  128.                 branchName, ConfigConstants.CONFIG_KEY_MERGE);
  129.     }

  130.     /**
  131.      * Whether the branch is configured to be rebased
  132.      *
  133.      * @return {@code true} if the branch is configured to be rebased
  134.      * @since 3.5
  135.      */
  136.     public boolean isRebase() {
  137.         return getRebaseMode() != BranchRebaseMode.NONE;
  138.     }

  139.     /**
  140.      * Retrieves the config value of branch.[name].rebase.
  141.      *
  142.      * @return the {@link org.eclipse.jgit.lib.BranchConfig.BranchRebaseMode}
  143.      * @since 4.5
  144.      */
  145.     public BranchRebaseMode getRebaseMode() {
  146.         return config.getEnum(BranchRebaseMode.values(),
  147.                 ConfigConstants.CONFIG_BRANCH_SECTION, branchName,
  148.                 ConfigConstants.CONFIG_KEY_REBASE, BranchRebaseMode.NONE);
  149.     }

  150.     /**
  151.      * Finds the tracked remote tracking branch
  152.      *
  153.      * @param remote
  154.      *            Remote name
  155.      * @param mergeRef
  156.      *            merge Ref of the local branch tracking the remote tracking
  157.      *            branch
  158.      * @return full remote tracking branch name or null
  159.      */
  160.     private String findRemoteTrackingBranch(String remote, String mergeRef) {
  161.         RemoteConfig remoteConfig;
  162.         try {
  163.             remoteConfig = new RemoteConfig(config, remote);
  164.         } catch (URISyntaxException e) {
  165.             return null;
  166.         }
  167.         for (RefSpec refSpec : remoteConfig.getFetchRefSpecs()) {
  168.             if (refSpec.matchSource(mergeRef)) {
  169.                 RefSpec expanded = refSpec.expandFromSource(mergeRef);
  170.                 return expanded.getDestination();
  171.             }
  172.         }
  173.         return null;
  174.     }

  175.     private String getRemoteOrDefault() {
  176.         String remote = getRemote();
  177.         if (remote == null) {
  178.             return Constants.DEFAULT_REMOTE_NAME;
  179.         }
  180.         return remote;
  181.     }
  182. }