Пример #1
0
 @Nonnull
 public static String ensureRefPrefix(@Nonnull String name, @Nonnull String prefix) {
   if (!matchesPrefix(name, prefix)) {
     if (matchesRefPrefix(name))
       throw new IllegalArgumentException("\"" + prefix + "\" is not the prefix of " + name);
     name = prefix + name;
   }
   if (!Repository.isValidRefName(name))
     throw new IllegalArgumentException(name + " is not a valid ref name");
   return name;
 }
Пример #2
0
  private void validateCommands() {
    for (final ReceiveCommand cmd : commands) {
      final Ref ref = cmd.getRef();
      if (cmd.getResult() != Result.NOT_ATTEMPTED) continue;

      if (cmd.getType() == ReceiveCommand.Type.DELETE && !isAllowDeletes()) {
        // Deletes are not supported on this repository.
        //
        cmd.setResult(Result.REJECTED_NODELETE);
        continue;
      }

      if (cmd.getType() == ReceiveCommand.Type.CREATE) {
        if (!isAllowCreates()) {
          cmd.setResult(Result.REJECTED_NOCREATE);
          continue;
        }

        if (ref != null && !isAllowNonFastForwards()) {
          // Creation over an existing ref is certainly not going
          // to be a fast-forward update. We can reject it early.
          //
          cmd.setResult(Result.REJECTED_NONFASTFORWARD);
          continue;
        }

        if (ref != null) {
          // A well behaved client shouldn't have sent us a
          // create command for a ref we advertised to it.
          //
          cmd.setResult(
              Result.REJECTED_OTHER_REASON,
              MessageFormat.format(JGitText.get().refAlreadyExists, ref));
          continue;
        }
      }

      if (cmd.getType() == ReceiveCommand.Type.DELETE
          && ref != null
          && !ObjectId.zeroId().equals(cmd.getOldId())
          && !ref.getObjectId().equals(cmd.getOldId())) {
        // Delete commands can be sent with the old id matching our
        // advertised value, *OR* with the old id being 0{40}. Any
        // other requested old id is invalid.
        //
        cmd.setResult(Result.REJECTED_OTHER_REASON, JGitText.get().invalidOldIdSent);
        continue;
      }

      if (cmd.getType() == ReceiveCommand.Type.UPDATE) {
        if (ref == null) {
          // The ref must have been advertised in order to be updated.
          //
          cmd.setResult(Result.REJECTED_OTHER_REASON, JGitText.get().noSuchRef);
          continue;
        }

        if (!ref.getObjectId().equals(cmd.getOldId())) {
          // A properly functioning client will send the same
          // object id we advertised.
          //
          cmd.setResult(Result.REJECTED_OTHER_REASON, JGitText.get().invalidOldIdSent);
          continue;
        }

        // Is this possibly a non-fast-forward style update?
        //
        RevObject oldObj, newObj;
        try {
          oldObj = walk.parseAny(cmd.getOldId());
        } catch (IOException e) {
          cmd.setResult(Result.REJECTED_MISSING_OBJECT, cmd.getOldId().name());
          continue;
        }

        try {
          newObj = walk.parseAny(cmd.getNewId());
        } catch (IOException e) {
          cmd.setResult(Result.REJECTED_MISSING_OBJECT, cmd.getNewId().name());
          continue;
        }

        if (oldObj instanceof RevCommit && newObj instanceof RevCommit) {
          try {
            if (!walk.isMergedInto((RevCommit) oldObj, (RevCommit) newObj)) {
              cmd.setType(ReceiveCommand.Type.UPDATE_NONFASTFORWARD);
            }
          } catch (MissingObjectException e) {
            cmd.setResult(Result.REJECTED_MISSING_OBJECT, e.getMessage());
          } catch (IOException e) {
            cmd.setResult(Result.REJECTED_OTHER_REASON);
          }
        } else {
          cmd.setType(ReceiveCommand.Type.UPDATE_NONFASTFORWARD);
        }
      }

      if (!cmd.getRefName().startsWith(Constants.R_REFS)
          || !Repository.isValidRefName(cmd.getRefName())) {
        cmd.setResult(Result.REJECTED_OTHER_REASON, JGitText.get().funnyRefname);
      }
    }
  }
Пример #3
0
  /**
   * @throws RefNotFoundException if the old branch can not be found (branch with provided old name
   *     does not exist or old name resolves to a tag)
   * @throws InvalidRefNameException if the provided new name is <code>null</code> or otherwise
   *     invalid
   * @throws RefAlreadyExistsException if a branch with the new name already exists
   * @throws DetachedHeadException if rename is tried without specifying the old name and HEAD is
   *     detached
   */
  public Ref call()
      throws GitAPIException, RefNotFoundException, InvalidRefNameException,
          RefAlreadyExistsException, DetachedHeadException {
    checkCallable();

    if (newName == null)
      throw new InvalidRefNameException(
          MessageFormat.format(JGitText.get().branchNameInvalid, "<null>")); // $NON-NLS-1$

    try {
      String fullOldName;
      String fullNewName;
      if (repo.findRef(newName) != null)
        throw new RefAlreadyExistsException(
            MessageFormat.format(JGitText.get().refAlreadyExists1, newName));
      if (oldName != null) {
        Ref ref = repo.findRef(oldName);
        if (ref == null)
          throw new RefNotFoundException(
              MessageFormat.format(JGitText.get().refNotResolved, oldName));
        if (ref.getName().startsWith(Constants.R_TAGS))
          throw new RefNotFoundException(
              MessageFormat.format(JGitText.get().renameBranchFailedBecauseTag, oldName));
        fullOldName = ref.getName();
      } else {
        fullOldName = repo.getFullBranch();
        if (fullOldName == null) {
          throw new NoHeadException(JGitText.get().invalidRepositoryStateNoHead);
        }
        if (ObjectId.isId(fullOldName)) throw new DetachedHeadException();
      }

      if (fullOldName.startsWith(Constants.R_REMOTES)) fullNewName = Constants.R_REMOTES + newName;
      else {
        fullNewName = Constants.R_HEADS + newName;
      }

      if (!Repository.isValidRefName(fullNewName))
        throw new InvalidRefNameException(
            MessageFormat.format(JGitText.get().branchNameInvalid, fullNewName));

      RefRename rename = repo.renameRef(fullOldName, fullNewName);
      Result renameResult = rename.rename();

      setCallable(false);

      if (Result.RENAMED != renameResult)
        throw new JGitInternalException(
            MessageFormat.format(JGitText.get().renameBranchUnexpectedResult, renameResult.name()));

      if (fullNewName.startsWith(Constants.R_HEADS)) {
        String shortOldName = fullOldName.substring(Constants.R_HEADS.length());
        final StoredConfig repoConfig = repo.getConfig();
        // Copy all configuration values over to the new branch
        for (String name :
            repoConfig.getNames(ConfigConstants.CONFIG_BRANCH_SECTION, shortOldName)) {
          String[] values =
              repoConfig.getStringList(ConfigConstants.CONFIG_BRANCH_SECTION, shortOldName, name);
          if (values.length == 0) continue;
          // Keep any existing values already configured for the
          // new branch name
          String[] existing =
              repoConfig.getStringList(ConfigConstants.CONFIG_BRANCH_SECTION, newName, name);
          if (existing.length > 0) {
            String[] newValues = new String[values.length + existing.length];
            System.arraycopy(existing, 0, newValues, 0, existing.length);
            System.arraycopy(values, 0, newValues, existing.length, values.length);
            values = newValues;
          }

          repoConfig.setStringList(
              ConfigConstants.CONFIG_BRANCH_SECTION, newName, name, Arrays.asList(values));
        }
        repoConfig.unsetSection(ConfigConstants.CONFIG_BRANCH_SECTION, shortOldName);
        repoConfig.save();
      }

      Ref resultRef = repo.findRef(newName);
      if (resultRef == null)
        throw new JGitInternalException(JGitText.get().renameBranchFailedUnknownReason);
      return resultRef;
    } catch (IOException ioe) {
      throw new JGitInternalException(ioe.getMessage(), ioe);
    }
  }