public Change getChange(Project project) {
    // todo unify with
    if (myChange == null) {
      File baseDir = new File(project.getBaseDir().getPath());

      File file = getAbsolutePath(baseDir, myBeforePath);
      FilePath beforePath = VcsUtil.getFilePath(file, false);
      beforePath.refresh();
      ContentRevision beforeRevision = null;
      if (myFileStatus != FileStatus.ADDED) {
        beforeRevision =
            new CurrentContentRevision(beforePath) {
              @Override
              @NotNull
              public VcsRevisionNumber getRevisionNumber() {
                return new TextRevisionNumber(VcsBundle.message("local.version.title"));
              }
            };
      }
      ContentRevision afterRevision = null;
      if (myFileStatus != FileStatus.DELETED) {
        FilePath afterPath = VcsUtil.getFilePath(getAbsolutePath(baseDir, myAfterPath), false);
        afterRevision = new PatchedContentRevision(project, beforePath, afterPath);
      }
      myChange = new Change(beforeRevision, afterRevision, myFileStatus);
    }
    return myChange;
  }
  @Nullable
  private byte[] loadFromVersionControl(long date, VirtualFile f) {
    try {
      final AbstractVcs vcs = VcsUtil.getVcsFor(myProject, f);
      if (vcs == null) return null;

      final VcsHistoryProvider historyProvider = vcs.getVcsHistoryProvider();
      if (historyProvider == null) return null;

      final FilePath filePath = VcsContextFactory.SERVICE.getInstance().createFilePathOn(f);
      final VcsHistorySession session = historyProvider.createSessionFor(filePath);
      if (session == null) return null;

      final List<VcsFileRevision> list = session.getRevisionList();

      if (list != null) {
        for (VcsFileRevision revision : list) {
          final Date revisionDate = revision.getRevisionDate();
          if (revisionDate == null) {
            return null;
          }

          if (revisionDate.getTime() < date) {
            return revision.loadContent();
          }
        }
      }
    } catch (Exception e) {
      LOG.info(e);
      return null;
    }
    return null;
  }
예제 #3
0
  @Nullable
  public static VirtualFile findGitDir(@NotNull VirtualFile rootDir) {
    VirtualFile child = rootDir.findChild(DOT_GIT);
    if (child == null) {
      return null;
    }
    if (child.isDirectory()) {
      return child;
    }

    // this is standard for submodules, although probably it can
    String content;
    try {
      content = readFile(child);
    } catch (IOException e) {
      throw new RuntimeException("Couldn't read " + child, e);
    }
    String pathToDir;
    String prefix = "gitdir:";
    if (content.startsWith(prefix)) {
      pathToDir = content.substring(prefix.length()).trim();
    } else {
      pathToDir = content;
    }

    if (!FileUtil.isAbsolute(pathToDir)) {
      String canonicalPath = FileUtil.toCanonicalPath(FileUtil.join(rootDir.getPath(), pathToDir));
      if (canonicalPath == null) {
        return null;
      }
      pathToDir = FileUtil.toSystemIndependentName(canonicalPath);
    }
    return VcsUtil.getVirtualFileWithRefresh(new File(pathToDir));
  }
 /** @return File encoding or <code>null</code> if the encoding is unknown. */
 @Nullable
 private static Charset calcEncoding(File file) {
   VirtualFile vf = VcsUtil.getVirtualFile(file);
   return ApplicationManager.getApplication().isDisposed()
       ? null
       : EncodingManager.getInstance().getEncoding(vf, false);
 }
 @NotNull
 private static FilePath rebasePath(
     @NotNull FilePath oldBase, @NotNull FilePath newBase, @NotNull FilePath path) {
   String relativePath =
       ObjectUtils.assertNotNull(FileUtil.getRelativePath(oldBase.getPath(), path.getPath(), '/'));
   return VcsUtil.getFilePath(newBase.getPath() + "/" + relativePath, path.isDirectory());
 }
      public MyDiffRequestProducer(
          @NotNull VirtualFilePointer filePointer, @NotNull FileStatus fileStatus) {
        myFilePointer = filePointer;
        myFileStatus = fileStatus;

        myFilePath = VcsUtil.getFilePath(myFilePointer.getPresentableUrl(), false);
      }
 public ThreeState haveChangesUnder(@NotNull VirtualFile virtualFile) {
   FilePath dir = VcsUtil.getFilePath(virtualFile);
   FilePath changeCandidate = myIdx.getAffectedPaths().ceiling(dir);
   if (changeCandidate == null) {
     return ThreeState.NO;
   }
   return FileUtil.isAncestorThreeState(dir.getPath(), changeCandidate.getPath(), false);
 }
예제 #8
0
 public static void addMappingIfSubRoot(
     @NotNull Project project, @NotNull String newRepositoryPath, @NotNull String vcsName) {
   if (project.getBasePath() != null
       && FileUtil.isAncestor(project.getBasePath(), newRepositoryPath, true)) {
     ProjectLevelVcsManager manager = ProjectLevelVcsManager.getInstance(project);
     manager.setDirectoryMappings(
         VcsUtil.addMapping(manager.getDirectoryMappings(), newRepositoryPath, vcsName));
   }
 }
  @NotNull
  private static Pair<FilePath, VirtualFile> getPathAndParentFile(@NotNull VcsContext context) {
    if (context.getSelectedFilesStream().findAny().isPresent()) {
      VirtualFile file = getIfSingle(context.getSelectedFilesStream());
      return file != null ? Pair.create(VcsUtil.getFilePath(file), file) : Pair.empty();
    }

    File[] ioFiles = context.getSelectedIOFiles();
    if (ioFiles != null && ioFiles.length > 0) {
      for (File ioFile : ioFiles) {
        VirtualFile parent = getParentVirtualFile(ioFile);
        if (parent != null)
          return Pair.create(VcsUtil.getFilePath(parent, ioFile.getName()), parent);
      }
    }

    return Pair.empty();
  }
예제 #10
0
 public static HgFile getOriginalHgFile(Project project, VirtualFile root) {
   HgFile hgFile = new HgFile(root, VcsUtil.getFilePath(root.getPath()));
   if (project.isDisposed()) {
     return hgFile;
   }
   FilePath originalFileName =
       HgUtil.getOriginalFileName(hgFile.toFilePath(), ChangeListManager.getInstance(project));
   return new HgFile(hgFile.getRepo(), originalFileName);
 }
 /**
  * Revert files from the list
  *
  * @param project the project
  * @param root the vcs root
  * @param files the files to revert
  */
 private static void revertFiles(Project project, VirtualFile root, ArrayList<String> files)
     throws VcsException {
   // TODO consider deleted files
   GitRollbackEnvironment rollback = GitRollbackEnvironment.getInstance(project);
   ArrayList<FilePath> list = new ArrayList<FilePath>(files.size());
   for (String p : files) {
     list.add(VcsUtil.getFilePath(p));
   }
   rollback.revert(root, list);
 }
  GitRepositoryUpdater(GitRepository repository) {
    VirtualFile gitDir = repository.getGitDir();
    myWatchRequest = LocalFileSystem.getInstance().addRootToWatch(gitDir.getPath(), true);

    myRepositoryFiles = GitRepositoryFiles.getInstance(gitDir);
    visitGitDirVfs(gitDir);
    myHeadsDir = VcsUtil.getVirtualFile(myRepositoryFiles.getRefsHeadsPath());
    myRemotesDir = VcsUtil.getVirtualFile(myRepositoryFiles.getRefsRemotesPath());

    Project project = repository.getProject();
    myUpdateQueue =
        new QueueProcessor<GitRepository.TrackedTopic>(
            new Updater(repository), project.getDisposed());
    if (!project.isDisposed()) {
      myMessageBusConnection = project.getMessageBus().connect();
      myMessageBusConnection.subscribe(VirtualFileManager.VFS_CHANGES, this);
    } else {
      myMessageBusConnection = null;
    }
  }
  public void setNewBase(final VirtualFile base) {
    myBase = base;
    myNewContentRevision = null;
    myCurrentRevision = null;
    myAfterFile = null;
    myConflicts = null;

    final String beforeName = myPatch.getBeforeName();
    if (beforeName != null) {
      myIoCurrentBase = PathMerger.getFile(new File(myBase.getPath()), beforeName);
      myCurrentBase =
          myIoCurrentBase == null ? null : VcsUtil.getVirtualFileWithRefresh(myIoCurrentBase);
      myBaseExists = (myCurrentBase != null) && myCurrentBase.exists();
    } else {
      // creation
      final String afterName = myPatch.getAfterName();
      myBaseExists = true;
      myIoCurrentBase = PathMerger.getFile(new File(myBase.getPath()), afterName);
      myCurrentBase = VcsUtil.getVirtualFileWithRefresh(myIoCurrentBase);
    }
  }
예제 #14
0
  @Nullable
  private static VirtualFile guessRootForVcs(
      @NotNull Project project, @Nullable AbstractVcs vcs, @Nullable String defaultRootPathValue) {
    if (project.isDisposed()) return null;
    LOG.debug("Guessing vcs root...");
    ProjectLevelVcsManager vcsManager = ProjectLevelVcsManager.getInstance(project);
    if (vcs == null) {
      LOG.debug("Vcs not found.");
      return null;
    }
    String vcsName = vcs.getDisplayName();
    VirtualFile[] vcsRoots = vcsManager.getRootsUnderVcs(vcs);
    if (vcsRoots.length == 0) {
      LOG.debug("No " + vcsName + " roots in the project.");
      return null;
    }

    if (vcsRoots.length == 1) {
      VirtualFile onlyRoot = vcsRoots[0];
      LOG.debug("Only one " + vcsName + " root in the project, returning: " + onlyRoot);
      return onlyRoot;
    }

    // get remembered last visited repository root
    if (defaultRootPathValue != null) {
      VirtualFile recentRoot = VcsUtil.getVirtualFile(defaultRootPathValue);
      if (recentRoot != null) {
        LOG.debug("Returning the recent root: " + recentRoot);
        return recentRoot;
      }
    }

    // otherwise return the root of the project dir or the root containing the project dir, if there
    // is such
    VirtualFile projectBaseDir = project.getBaseDir();
    if (projectBaseDir == null) {
      VirtualFile firstRoot = vcsRoots[0];
      LOG.debug("Project base dir is null, returning the first root: " + firstRoot);
      return firstRoot;
    }
    VirtualFile rootCandidate;
    for (VirtualFile root : vcsRoots) {
      if (root.equals(projectBaseDir) || VfsUtilCore.isAncestor(root, projectBaseDir, true)) {
        LOG.debug("The best candidate: " + root);
        return root;
      }
    }
    rootCandidate = vcsRoots[0];
    LOG.debug("Returning the best candidate: " + rootCandidate);
    return rootCandidate;
  }
예제 #15
0
  private Change getChange(GitVirtualFile file) {
    if (file == null) return null;
    ContentRevision beforeRev =
        new GitContentRevision(
            file,
            new GitRevisionNumber(GitRevisionNumber.TIP, new Date(file.getModificationStamp())),
            project);
    ContentRevision afterRev = CurrentContentRevision.create(VcsUtil.getFilePath(file.getPath()));

    Change c = null;
    switch (file.getStatus()) {
      case UNMERGED:
        {
          c = new Change(beforeRev, afterRev, FileStatus.MERGED_WITH_CONFLICTS);
          break;
        }
      case ADDED:
        {
          c = new Change(null, afterRev, FileStatus.ADDED);
          break;
        }
      case DELETED:
        {
          c = new Change(beforeRev, null, FileStatus.DELETED);
          break;
        }
      case COPY:
      case RENAME:
      case MODIFIED:
        {
          c = new Change(beforeRev, afterRev, FileStatus.MODIFIED);
          break;
        }
      case UNMODIFIED:
        {
          break;
        }
      case IGNORED:
        {
          c = new Change(null, afterRev, FileStatus.IGNORED);
          break;
        }
      case UNVERSIONED:
      default:
        {
          c = new Change(null, afterRev, FileStatus.UNKNOWN);
        }
    }
    return c;
  }
예제 #16
0
 /**
  * Return a git root for the file (the parent directory with ".git" subdirectory)
  *
  * @param file the file to check
  * @return git root for the file or null if the file is not not under Git
  * @deprecated because uses the java.io.File.
  * @use GitRepositoryManager#getRepositoryForFile().
  */
 @Nullable
 public static VirtualFile gitRootOrNull(final VirtualFile file) {
   if (file instanceof AbstractVcsVirtualFile) {
     return getGitRootOrNull(VcsUtil.getFilePath(file.getPath()));
   }
   VirtualFile root = file;
   while (root != null) {
     if (root.findFileByRelativePath(DOT_GIT) != null) {
       return root;
     }
     root = root.getParent();
   }
   return root;
 }
  private void processRecursively(final VirtualFile vFile, final SVNDepth prevDepth) {
    if (SVNDepth.EMPTY.equals(prevDepth)) return;
    if (myPartner.isIgnoredIdeaLevel(vFile)) {
      myReceiver.processIgnored(vFile);
      return;
    }
    final SVNDepth newDepth =
        SVNDepth.INFINITY.equals(prevDepth) ? SVNDepth.INFINITY : SVNDepth.EMPTY;

    final SVNStatusClient childClient = myPartner.createStatusClient();
    final VirtualFile[] children = vFile.getChildren();
    for (VirtualFile child : children) {
      final FilePath filePath = VcsUtil.getFilePath(child.getPath(), child.isDirectory());
      // recursiveness is used ONLY for search of working copies that have unversioned files above
      final MyItem childItem = new MyItem(myProject, filePath, newDepth, childClient, true);
      myQueue.add(childItem);
    }
  }
  public Map<VirtualFile, RepositoryLocation> getRoots() {
    myContentRoots = myPlManager.getRootsUnderVcs(myVcs);

    List<VirtualFile> roots = new ArrayList<>();
    final List<VcsDirectoryMapping> mappings = myPlManager.getDirectoryMappings(myVcs);
    for (VcsDirectoryMapping mapping : mappings) {
      if (mapping.isDefaultMapping()) {
        if (myVcs.equals(myPlManager.getVcsFor(myProject.getBaseDir()))) {
          roots.add(myProject.getBaseDir());
        }
      } else {
        VirtualFile newFile = LocalFileSystem.getInstance().findFileByPath(mapping.getDirectory());
        if (newFile == null) {
          newFile = LocalFileSystem.getInstance().refreshAndFindFileByPath(mapping.getDirectory());
        }
        if (newFile != null) {
          roots.add(newFile);
        } else {
          LOG.info("Can not file virtual file for root: " + mapping.getDirectory());
        }
      }
    }
    ContainerUtil.addAll(roots, myContentRoots);
    final Map<VirtualFile, RepositoryLocation> result = new HashMap<>();
    for (Iterator<VirtualFile> iterator = roots.iterator(); iterator.hasNext(); ) {
      final VirtualFile vf = iterator.next();
      final RepositoryLocation location =
          myLocationCache.getLocation(myVcs, VcsUtil.getFilePath(vf), false);
      if (location != null) {
        result.put(vf, location);
      } else {
        iterator.remove();
      }
    }
    roots = myVcs.filterUniqueRoots(roots, IntoSelfVirtualFileConvertor.getInstance());
    result.keySet().retainAll(roots);

    logRoots(roots);
    return result;
  }
 @Override
 protected void hyperlinkActivated(
     @NotNull Notification notification, @NotNull HyperlinkEvent event) {
   if (event.getDescription().equals("configure") && !myProject.isDisposed()) {
     ShowSettingsUtil.getInstance()
         .showSettingsDialog(myProject, ActionsBundle.message("group.VcsGroup.text"));
     Collection<VcsRootError> errorsAfterPossibleFix = getInstance(myProject).scan();
     if (errorsAfterPossibleFix.isEmpty() && !notification.isExpired()) {
       notification.expire();
     }
   } else if (event.getDescription().equals("ignore")) {
     mySettings.addIgnoredUnregisteredRoots(
         ContainerUtil.map(myImportantUnregisteredRoots, PATH_FROM_ROOT_ERROR));
     notification.expire();
   } else if (event.getDescription().equals("add")) {
     List<VcsDirectoryMapping> mappings = myVcsManager.getDirectoryMappings();
     for (VcsRootError root : myImportantUnregisteredRoots) {
       mappings = VcsUtil.addMapping(mappings, root.getMapping(), root.getVcsKey().getName());
     }
     myVcsManager.setDirectoryMappings(mappings);
   }
 }
    public void handleStatus(final SVNStatus status) throws SVNException {
      myPartner.checkCanceled();
      final File ioFile = status.getFile();
      checkIfCopyRootWasReported();

      final LocalFileSystem lfs = LocalFileSystem.getInstance();
      VirtualFile vFile = lfs.findFileByIoFile(ioFile);
      if (vFile == null) {
        vFile = lfs.refreshAndFindFileByIoFile(ioFile);
      }
      if ((vFile != null) && myPartner.isExcluded(vFile)) return;

      if ((vFile != null) && (SvnVcs.svnStatusIsUnversioned(status))) {
        myReceiver.processUnversioned(vFile);
        if (vFile.isDirectory()) {
          processRecursively(vFile, myCurrentItem.getDepth());
        }
      } else {
        final FilePath path = VcsUtil.getFilePath(ioFile, status.getKind().equals(SVNNodeKind.DIR));
        myReceiver.process(path, status);
      }
    }
  public byte[] getContent() throws IOException, VcsException {
    byte[] result;

    if (SVNRevision.HEAD.equals(myRevision)) {
      result = loadContent();
    } else {
      result =
          ContentRevisionCache.getOrLoadAsBytes(
              myVCS.getProject(),
              VcsUtil.getFilePathOnNonLocal(myURL, false),
              getRevisionNumber(),
              myVCS.getKeyInstanceMethod(),
              ContentRevisionCache.UniqueType.REMOTE_CONTENT,
              new Throwable2Computable<byte[], VcsException, IOException>() {
                @Override
                public byte[] compute() throws VcsException, IOException {
                  return loadContent();
                }
              });
    }

    return result;
  }
예제 #22
0
 private VcsHistorySession getHistorySession(String relativePath) throws VcsException {
   return HgVcs.getInstance(myProject)
       .getVcsHistoryProvider()
       .createSessionFor(VcsUtil.getFilePath(new File(myProjectDir, relativePath), false));
 }
 @Nullable
 private VirtualFile getRootForPath(final String s) {
   return myVcsManager.getVcsRootFor(VcsUtil.getFilePath(s, false));
 }
예제 #24
0
  @NotNull
  public MergeData loadRevisions(@NotNull final VirtualFile file) throws VcsException {
    final MergeData data = new MergeData();
    VcsRunnable runnable =
        new VcsRunnable() {
          public void run() throws VcsException {
            File oldFile = null;
            File newFile = null;
            File workingFile = null;
            boolean mergeCase = false;
            SvnVcs vcs = SvnVcs.getInstance(myProject);
            Info info = vcs.getInfo(file);

            if (info != null) {
              oldFile = info.getConflictOldFile();
              newFile = info.getConflictNewFile();
              workingFile = info.getConflictWrkFile();
              mergeCase = workingFile == null || workingFile.getName().contains("working");
              // for debug
              if (workingFile == null) {
                LOG.info(
                    "Null working file when merging text conflict for "
                        + file.getPath()
                        + " old file: "
                        + oldFile
                        + " new file: "
                        + newFile);
              }
              if (mergeCase) {
                // this is merge case
                oldFile = info.getConflictNewFile();
                newFile = info.getConflictOldFile();
                workingFile = info.getConflictWrkFile();
              }
              data.LAST_REVISION_NUMBER = new SvnRevisionNumber(info.getRevision());
            } else {
              throw new VcsException("Could not get info for " + file.getPath());
            }
            if (oldFile == null || newFile == null || workingFile == null) {
              ByteArrayOutputStream bos = getBaseRevisionContents(vcs, file);
              data.ORIGINAL = bos.toByteArray();
              data.LAST = bos.toByteArray();
              data.CURRENT = readFile(new File(file.getPath()));
            } else {
              data.ORIGINAL = readFile(oldFile);
              data.LAST = readFile(newFile);
              data.CURRENT = readFile(workingFile);
            }
            if (mergeCase) {
              final ByteArrayOutputStream contents = getBaseRevisionContents(vcs, file);
              if (!Arrays.equals(contents.toByteArray(), data.ORIGINAL)) {
                // swap base and server: another order of merge arguments
                byte[] original = data.ORIGINAL;
                data.ORIGINAL = data.LAST;
                data.LAST = original;
              }
            }
          }
        };
    VcsUtil.runVcsProcessWithProgress(
        runnable,
        VcsBundle.message("multiple.file.merge.loading.progress.title"),
        false,
        myProject);

    return data;
  }
  /**
   * Preform a merge commit
   *
   * @param project a project
   * @param root a vcs root
   * @param added added files
   * @param removed removed files
   * @param messageFile a message file for commit
   * @param author an author
   * @param exceptions the list of exceptions to report
   * @param partialOperation
   * @return true if merge commit was successful
   */
  private static boolean mergeCommit(
      final Project project,
      final VirtualFile root,
      final Set<FilePath> added,
      final Set<FilePath> removed,
      final File messageFile,
      final String author,
      List<VcsException> exceptions,
      @NotNull final PartialOperation partialOperation) {
    HashSet<FilePath> realAdded = new HashSet<FilePath>();
    HashSet<FilePath> realRemoved = new HashSet<FilePath>();
    // perform diff
    GitSimpleHandler diff = new GitSimpleHandler(project, root, GitCommand.DIFF);
    diff.setSilent(true);
    diff.setStdoutSuppressed(true);
    diff.addParameters("--diff-filter=ADMRUX", "--name-status", "HEAD");
    diff.endOptions();
    String output;
    try {
      output = diff.run();
    } catch (VcsException ex) {
      exceptions.add(ex);
      return false;
    }
    String rootPath = root.getPath();
    for (StringTokenizer lines = new StringTokenizer(output, "\n", false);
        lines.hasMoreTokens(); ) {
      String line = lines.nextToken().trim();
      if (line.length() == 0) {
        continue;
      }
      String[] tk = line.split("\t");
      switch (tk[0].charAt(0)) {
        case 'M':
        case 'A':
          realAdded.add(VcsUtil.getFilePath(rootPath + "/" + tk[1]));
          break;
        case 'D':
          realRemoved.add(VcsUtil.getFilePathForDeletedFile(rootPath + "/" + tk[1], false));
          break;
        default:
          throw new IllegalStateException("Unexpected status: " + line);
      }
    }
    realAdded.removeAll(added);
    realRemoved.removeAll(removed);
    if (realAdded.size() != 0 || realRemoved.size() != 0) {

      final List<FilePath> files = new ArrayList<FilePath>();
      files.addAll(realAdded);
      files.addAll(realRemoved);
      final Ref<Boolean> mergeAll = new Ref<Boolean>();
      try {
        GuiUtils.runOrInvokeAndWait(
            new Runnable() {
              public void run() {
                String message =
                    GitBundle.message("commit.partial.merge.message", partialOperation.getName());
                SelectFilePathsDialog dialog =
                    new SelectFilePathsDialog(
                        project,
                        files,
                        message,
                        null,
                        "Commit All Files",
                        CommonBundle.getCancelButtonText(),
                        false);
                dialog.setTitle(GitBundle.getString("commit.partial.merge.title"));
                dialog.show();
                mergeAll.set(dialog.isOK());
              }
            });
      } catch (RuntimeException ex) {
        throw ex;
      } catch (Exception ex) {
        throw new RuntimeException("Unable to invoke a message box on AWT thread", ex);
      }
      if (!mergeAll.get()) {
        return false;
      }
      // update non-indexed files
      if (!updateIndex(project, root, realAdded, realRemoved, exceptions)) {
        return false;
      }
      for (FilePath f : realAdded) {
        VcsDirtyScopeManager.getInstance(project).fileDirty(f);
      }
      for (FilePath f : realRemoved) {
        VcsDirtyScopeManager.getInstance(project).fileDirty(f);
      }
    }
    // perform merge commit
    try {
      GitSimpleHandler handler = new GitSimpleHandler(project, root, GitCommand.COMMIT);
      handler.setStdoutSuppressed(false);
      handler.addParameters("-F", messageFile.getAbsolutePath());
      if (author != null) {
        handler.addParameters("--author=" + author);
      }
      handler.endOptions();
      handler.run();
      GitRepositoryManager manager = GitUtil.getRepositoryManager(project);
      manager.updateRepository(root);
    } catch (VcsException ex) {
      exceptions.add(ex);
      return false;
    }
    return true;
  }
 @Override
 protected boolean isFileDirty(final VcsDirtyScope scope, final VirtualFile file) {
   if (scope == null) return true;
   if (fileDropped(file)) return true;
   return scope.belongsTo(VcsUtil.getFilePath(file));
 }
 @Nullable
 private static VirtualFile getFileForEvent(VFileEvent event) {
   return VcsUtil.getVirtualFile(event.getPath());
 }
  @NotNull
  @Override
  public MergeData loadRevisions(final VirtualFile file) throws VcsException {
    final MergeData mergeData = new MergeData();
    final VcsRunnable runnable =
        new VcsRunnable() {
          public void run() throws VcsException {
            final HgWorkingCopyRevisionsCommand command =
                new HgWorkingCopyRevisionsCommand(myProject);
            final VirtualFile repo = HgUtil.getHgRootOrThrow(myProject, file);
            final HgFile hgFile = new HgFile(myProject, file);

            HgRevisionNumber serverRevisionNumber;
            HgRevisionNumber localRevisionNumber;
            HgRevisionNumber baseRevisionNumber = null;
            // there are two possibilities: we have checked in local changes in the selected file or
            // we didn't.
            if (wasFileCheckedIn(repo, file)) {
              // 1. We checked in.
              // We have a merge in progress, which means we have 2 heads (parents).
              // the second one is "their" revision pulled from the parent repo,
              // first parent is the local change.
              // to retrieve the base version we get the parent of the local change, i.e. the [only]
              // parent of the first parent.
              // Whick one is local revision depends on which one is merged with,
              // i.e if you update to 17 revision and then merge it woth 23, so 17 is your local and
              // 17->parent is your base revision.
              // This may produce misunderstanding when you update your project with merging (your
              // update firstly to next revisions  and then
              // merge with previous). see
              // http://hgbook.red-bean.com/read/managing-releases-and-branchy-development.html
              final Couple<HgRevisionNumber> parents = command.parents(repo, file);
              serverRevisionNumber = parents.second;
              localRevisionNumber = parents.first;
              final HgContentRevision local =
                  new HgContentRevision(myProject, hgFile, localRevisionNumber);
              mergeData.CURRENT = local.getContentAsBytes();
              // we are sure that we have a common ancestor, because otherwise we'll get "repository
              // is unrelated" error while pulling,
              // due to different root changesets which is prohibited.
              // Find common ancestor of two revisions : hg debugancestor rev1 rev2
              // Using quotes may produce wrong escaping errors on Unix-type systems
              List<String> arguments = new ArrayList<String>();
              String localChangeset = localRevisionNumber.getChangeset();
              String serverChangeset = serverRevisionNumber.getChangeset();
              arguments.add(
                  StringUtil.isEmptyOrSpaces(localChangeset)
                      ? localRevisionNumber.getRevision()
                      : localChangeset);
              arguments.add(
                  StringUtil.isEmptyOrSpaces(serverChangeset)
                      ? serverRevisionNumber.getRevision()
                      : serverChangeset);
              HgCommandResult result =
                  new HgPromptCommandExecutor(myProject)
                      .executeInCurrentThread(repo, "debugancestor", arguments);
              if (result != null) {
                String output = result.getRawOutput();
                final List<String> parts = StringUtil.split(output, ":");
                if (parts.size() < 2) {
                  LOG.info("Couldn't parse result of debugancestor command execution " + arguments);
                  new HgCommandResultNotifier(myProject)
                      .notifyError(
                          null,
                          HgVcsMessages.message("hg4idea.error.debugancestor.command.execution"),
                          HgVcsMessages.message("hg4idea.error.debugancestor.command.description"));
                } else {
                  baseRevisionNumber = HgRevisionNumber.getInstance(parts.get(0), parts.get(1));
                }
              } else {
                LOG.info(
                    HgVcsMessages.message("hg4idea.error.debugancestor.command.execution")
                        + arguments);
                new HgCommandResultNotifier(myProject)
                    .notifyError(
                        null,
                        HgVcsMessages.message("hg4idea.error.debugancestor.command.execution"),
                        HgVcsMessages.message("hg4idea.error.debugancestor.command.description"));
              }
            } else {
              // 2. local changes are not checked in.
              // then there is only one parent, which is server changes.
              // local changes are retrieved from the file system, they are not in the Mercurial
              // yet.
              // base is the only parent of server changes.
              serverRevisionNumber = command.parents(repo, file).first;
              baseRevisionNumber = command.parents(repo, file, serverRevisionNumber).first;
              final File origFile = new File(file.getPath() + ".orig");
              try {
                mergeData.CURRENT = VcsUtil.getFileByteContent(origFile);
              } catch (IOException e) {
                LOG.info("Couldn't retrieve byte content of the file: " + origFile.getPath(), e);
              }
            }

            if (baseRevisionNumber != null) {
              final HgContentRevision base =
                  new HgContentRevision(myProject, hgFile, baseRevisionNumber);
              // if file doesn't exist in ancestor revision the base revision should be empty
              mergeData.ORIGINAL =
                  base.getContent() != null ? base.getContentAsBytes() : new byte[0];
            } else { // no base revision means that the file was added simultaneously with different
                     // content in both repositories
              mergeData.ORIGINAL = new byte[0];
            }
            final HgContentRevision server =
                new HgContentRevision(myProject, hgFile, serverRevisionNumber);
            mergeData.LAST = server.getContentAsBytes();
            file.refresh(false, false);
          }
        };
    VcsUtil.runVcsProcessWithProgress(
        runnable,
        VcsBundle.message("multiple.file.merge.loading.progress.title"),
        false,
        myProject);
    return mergeData;
  }
 @Deprecated
 @Override
 public FileStatus getStatus(File file) {
   return myWorker.getStatus(VcsUtil.getFilePath(file));
 }
예제 #30
0
 protected VirtualFile makeFile(File file) throws IOException {
   file.createNewFile();
   VcsDirtyScopeManager.getInstance(myProject).fileDirty(myWorkingCopyDir);
   LocalFileSystem.getInstance().refresh(false);
   return VcsUtil.getVirtualFile(file);
 }