private Couple<String> keyForChange(final Change change) {
   final FilePath beforePath = ChangesUtil.getBeforePath(change);
   final String beforeKey = beforePath == null ? null : beforePath.getIOFile().getAbsolutePath();
   final FilePath afterPath = ChangesUtil.getAfterPath(change);
   final String afterKey = afterPath == null ? null : afterPath.getIOFile().getAbsolutePath();
   return Couple.of(beforeKey, afterKey);
 }
  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;
  }
 /**
  * Sort changes by roots
  *
  * @param changes a change list
  * @param exceptions exceptions to collect
  * @return sorted changes
  */
 private static Map<VirtualFile, Collection<Change>> sortChangesByGitRoot(
     @NotNull List<Change> changes, List<VcsException> exceptions) {
   Map<VirtualFile, Collection<Change>> result = new HashMap<VirtualFile, Collection<Change>>();
   for (Change change : changes) {
     final ContentRevision afterRevision = change.getAfterRevision();
     final ContentRevision beforeRevision = change.getBeforeRevision();
     // nothing-to-nothing change cannot happen.
     assert beforeRevision != null || afterRevision != null;
     // note that any path will work, because changes could happen within single vcs root
     final FilePath filePath =
         afterRevision != null ? afterRevision.getFile() : beforeRevision.getFile();
     final VirtualFile vcsRoot;
     try {
       // the parent paths for calculating roots in order to account for submodules that contribute
       // to the parent change. The path "." is never is valid change, so there should be no
       // problem
       // with it.
       vcsRoot = GitUtil.getGitRoot(filePath.getParentPath());
     } catch (VcsException e) {
       exceptions.add(e);
       continue;
     }
     Collection<Change> changeList = result.get(vcsRoot);
     if (changeList == null) {
       changeList = new ArrayList<Change>();
       result.put(vcsRoot, changeList);
     }
     changeList.add(change);
   }
   return result;
 }
 @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());
 }
  @NotNull
  private GitFileRevision createParentRevision(
      @NotNull GitRepository repository,
      @NotNull GitFileRevision currentRevision,
      @NotNull String parentHash)
      throws VcsException {
    FilePath currentRevisionPath = currentRevision.getPath();
    if (currentRevisionPath.isDirectory()) {
      // for directories the history doesn't follow renames
      return makeRevisionFromHash(currentRevisionPath, parentHash);
    }

    // can't limit by the path: in that case rename information will be missed
    Collection<Change> changes =
        GitChangeUtils.getDiff(
            myProject, repository.getRoot(), parentHash, currentRevision.getHash(), null);
    for (Change change : changes) {
      ContentRevision afterRevision = change.getAfterRevision();
      ContentRevision beforeRevision = change.getBeforeRevision();
      if (afterRevision != null && afterRevision.getFile().equals(currentRevisionPath)) {
        // if the file was renamed, taking the path how it was in the parent; otherwise the path
        // didn't change
        FilePath path =
            (beforeRevision != null ? beforeRevision.getFile() : afterRevision.getFile());
        return new GitFileRevision(myProject, path, new GitRevisionNumber(parentHash), true);
      }
    }
    LOG.error(
        String.format(
            "Could not find parent revision. Will use the path from parent revision. Current revision: %s, parent hash: %s",
            currentRevision, parentHash));
    return makeRevisionFromHash(currentRevisionPath, parentHash);
  }
  @CalledInAwt
  public static void refreshPassedFilesAndMoveToChangelist(
      @NotNull final Project project,
      final Collection<FilePath> directlyAffected,
      final Collection<VirtualFile> indirectlyAffected,
      final Consumer<Collection<FilePath>> targetChangelistMover) {
    final LocalFileSystem lfs = LocalFileSystem.getInstance();
    for (FilePath filePath : directlyAffected) {
      lfs.refreshAndFindFileByIoFile(filePath.getIOFile());
    }
    if (project.isDisposed()) return;

    final ChangeListManager changeListManager = ChangeListManager.getInstance(project);
    if (!directlyAffected.isEmpty() && targetChangelistMover != null) {
      changeListManager.invokeAfterUpdate(
          new Runnable() {
            @Override
            public void run() {
              targetChangelistMover.consume(directlyAffected);
            }
          },
          InvokeAfterUpdateMode.SYNCHRONOUS_CANCELLABLE,
          VcsBundle.message("change.lists.manager.move.changes.to.list"),
          new Consumer<VcsDirtyScopeManager>() {
            @Override
            public void consume(final VcsDirtyScopeManager vcsDirtyScopeManager) {
              markDirty(vcsDirtyScopeManager, directlyAffected, indirectlyAffected);
            }
          },
          null);
    } else {
      markDirty(VcsDirtyScopeManager.getInstance(project), directlyAffected, indirectlyAffected);
    }
  }
 public List<File> getAffectedPaths() {
   final SortedSet<FilePath> set = myIdx.getAffectedPaths();
   final List<File> result = new ArrayList<File>(set.size());
   for (FilePath path : set) {
     result.add(path.getIOFile());
   }
   return result;
 }
 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);
 }
Beispiel #9
0
 public static boolean canCreateRequest(Change change) {
   if (ChangesUtil.isTextConflictingChange(change)
       || change.isTreeConflict()
       || change.isPhantom()) return false;
   if (ShowDiffAction.isBinaryChange(change)) return false;
   final FilePath filePath = ChangesUtil.getFilePath(change);
   if (filePath.isDirectory()) return false;
   return true;
 }
  private static List<VirtualFile> impl(final Iterator<FilePath> iterator) {
    final MyProcessor processor = new MyProcessor();

    for (; iterator.hasNext(); ) {
      final FilePath root = iterator.next();
      final VirtualFile vf = root.getVirtualFile();
      if (vf == null) continue;
      VfsUtil.processFilesRecursively(vf, processor, processor);
    }
    return processor.getFound();
  }
 public static BeforeAfter<DiffContent> createBinaryDiffContents(
     final Project project, final Change change) throws VcsException {
   final FilePath filePath = ChangesUtil.getFilePath(change);
   try {
     return new BeforeAfter<DiffContent>(
         createBinaryFileContent(project, change.getBeforeRevision(), filePath.getName()),
         createBinaryFileContent(project, change.getAfterRevision(), filePath.getName()));
   } catch (IOException e) {
     throw new VcsException(e);
   }
 }
Beispiel #12
0
 public static void refreshFiles(Project project, HashSet<FilePath> paths) {
   for (FilePath path : paths) {
     VirtualFile vFile = path.getVirtualFile();
     if (vFile != null) {
       if (vFile.isDirectory()) {
         markFileAsDirty(project, vFile);
       } else {
         vFile.refresh(true, vFile.isDirectory());
       }
     }
   }
 }
 @NotNull
 private static Collection<VirtualFile> getVirtualFilesFromFilePaths(
     @NotNull Collection<FilePath> paths) {
   Collection<VirtualFile> files = new ArrayList<VirtualFile>(paths.size());
   for (FilePath path : paths) {
     VirtualFile file = path.getVirtualFile();
     if (file != null) {
       files.add(file);
     }
   }
   return files;
 }
  private void collectLogEntries(
      final ProgressIndicator indicator,
      FilePath file,
      VcsException[] exception,
      final Consumer<VcsFileRevision> result,
      final Ref<Boolean> supports15Ref)
      throws SVNException, VcsException {
    SVNWCClient wcClient = myVcs.createWCClient();
    SVNInfo info =
        wcClient.doInfo(new File(file.getIOFile().getAbsolutePath()), SVNRevision.UNDEFINED);
    wcClient.setEventHandler(
        new ISVNEventHandler() {
          public void handleEvent(SVNEvent event, double progress) throws SVNException {}

          public void checkCancelled() throws SVNCancelException {
            indicator.checkCanceled();
          }
        });
    if (info == null || info.getRepositoryRootURL() == null) {
      exception[0] =
          new VcsException("File ''{0}'' is not under version control" + file.getIOFile());
      return;
    }
    final String url = info.getURL() == null ? null : info.getURL().toString();
    String relativeUrl = url;
    final SVNURL repoRootURL = info.getRepositoryRootURL();

    final String root = repoRootURL.toString();
    if (url != null && url.startsWith(root)) {
      relativeUrl = url.substring(root.length());
    }
    if (indicator != null) {
      indicator.setText2(SvnBundle.message("progress.text2.changes.establishing.connection", url));
    }
    final SVNRevision pegRevision = info.getRevision();
    SVNLogClient client = myVcs.createLogClient();

    final boolean supports15 = SvnUtil.checkRepositoryVersion15(myVcs, url);
    supports15Ref.set(supports15);
    client.doLog(
        new File[] {new File(file.getIOFile().getAbsolutePath())},
        SVNRevision.HEAD,
        SVNRevision.create(1),
        SVNRevision.UNDEFINED,
        false,
        true,
        supports15,
        0,
        null,
        new MyLogEntryHandler(
            myVcs, url, pegRevision, relativeUrl, result, repoRootURL, file.getCharset()));
  }
 @Override
 protected void renderIcon(FilePath path) {
   final String module = myModules.get(path.getVirtualFile());
   if (module != null) {
     setIcon(PlatformIcons.CONTENT_ROOT_ICON_CLOSED);
   } else {
     if (path.isDirectory()) {
       setIcon(PlatformIcons.DIRECTORY_CLOSED_ICON);
     } else {
       setIcon(path.getFileType().getIcon());
     }
   }
 }
 private File[] getSelectedIoFiles() {
   final List<Change> changes = getSelectedChanges();
   final List<File> files = new ArrayList<>();
   for (Change change : changes) {
     final ContentRevision afterRevision = change.getAfterRevision();
     if (afterRevision != null) {
       final FilePath file = afterRevision.getFile();
       final File ioFile = file.getIOFile();
       files.add(ioFile);
     }
   }
   return files.toArray(new File[files.size()]);
 }
 private static SimpleDiffRequest createBinaryDiffRequest(
     final Project project, final Change change) throws VcsException {
   final FilePath filePath = ChangesUtil.getFilePath(change);
   final SimpleDiffRequest request = new SimpleDiffRequest(project, filePath.getPath());
   try {
     request.setContents(
         createBinaryFileContent(project, change.getBeforeRevision(), filePath.getName()),
         createBinaryFileContent(project, change.getAfterRevision(), filePath.getName()));
     return request;
   } catch (IOException e) {
     throw new VcsException(e);
   }
 }
 private static boolean directoryOrBinary(final Change change) {
   // todo instead for repository tab, filter directories (? ask remotely ? non leaf nodes)
   /*if ((change.getBeforeRevision() instanceof BinaryContentRevision) || (change.getAfterRevision() instanceof BinaryContentRevision)) {
     changesList.remove(i);
     continue;
   }*/
   final FilePath path = ChangesUtil.getFilePath(change);
   if (path.isDirectory()) {
     return !change.hasOtherLayers();
   }
   /*final FileType type = path.getFileType();
   if ((! FileTypes.UNKNOWN.equals(type)) && (type.isBinary())) {
     return true;
   }*/
   return false;
 }
 private void doShowDiff(
     @NotNull FilePath filePath,
     @NotNull VcsFileRevision revision1,
     @NotNull VcsFileRevision revision2,
     boolean autoSort) {
   if (!filePath.isDirectory()) {
     VcsHistoryUtil.showDifferencesInBackground(
         myProject, filePath, revision1, revision2, autoSort);
   } else if (revision2 instanceof CurrentRevision) {
     GitFileRevision left = (GitFileRevision) revision1;
     showDiffForDirectory(filePath, left.getHash(), null);
   } else if (revision1.equals(VcsFileRevision.NULL)) {
     GitFileRevision right = (GitFileRevision) revision2;
     showDiffForDirectory(filePath, null, right.getHash());
   } else {
     GitFileRevision left = (GitFileRevision) revision1;
     GitFileRevision right = (GitFileRevision) revision2;
     if (autoSort) {
       Pair<VcsFileRevision, VcsFileRevision> pair =
           VcsHistoryUtil.sortRevisions(revision1, revision2);
       left = (GitFileRevision) pair.first;
       right = (GitFileRevision) pair.second;
     }
     showDiffForDirectory(filePath, left.getHash(), right.getHash());
   }
 }
  /**
   * Gets info of the given commit and checks if it was a RENAME. If yes, returns the older file
   * path, which file was renamed from. If it's not a rename, returns null.
   */
  @Nullable
  private static FilePath getFirstCommitRenamePath(
      Project project, VirtualFile root, String commit, FilePath filePath) throws VcsException {
    // 'git show -M --name-status <commit hash>' returns the information about commit and detects
    // renames.
    // NB: we can't specify the filepath, because then rename detection will work only with the
    // '--follow' option, which we don't wanna use.
    final GitSimpleHandler h = new GitSimpleHandler(project, root, GitCommand.SHOW);
    final GitLogParser parser =
        new GitLogParser(project, GitLogParser.NameStatus.STATUS, HASH, COMMIT_TIME, SHORT_PARENTS);
    h.setNoSSH(true);
    h.setStdoutSuppressed(true);
    h.addParameters("-M", "--name-status", parser.getPretty(), "--encoding=UTF-8", commit);
    h.endOptions();
    final String output = h.run();
    final List<GitLogRecord> records = parser.parse(output);

    if (records.isEmpty()) return null;
    // we have information about all changed files of the commit. Extracting information about the
    // file we need.
    final List<Change> changes = records.get(0).parseChanges(project, root);
    for (Change change : changes) {
      if ((change.isMoved() || change.isRenamed())
          && filePath.equals(change.getAfterRevision().getFile())) {
        return change.getBeforeRevision().getFile();
      }
    }
    return null;
  }
  public void reportAppendableHistory(
      FilePath path, final VcsAppendableHistorySessionPartner partner) throws VcsException {
    final FilePath committedPath = ChangesUtil.getCommittedPath(myVcs.getProject(), path);

    final LogLoader logLoader;
    if (path.isNonLocal()) {
      logLoader = new RepositoryLoader(myVcs, path);
    } else {
      logLoader = new LocalLoader(myVcs, path);
    }

    try {
      logLoader.preliminary();
    } catch (SVNCancelException e) {
      return;
    } catch (SVNException e) {
      throw new VcsException(e);
    }
    logLoader.initSupports15();

    final MyHistorySession historySession =
        new MyHistorySession(
            Collections.<VcsFileRevision>emptyList(),
            committedPath,
            Boolean.TRUE.equals(logLoader.mySupport15),
            null);

    final Ref<Boolean> sessionReported = new Ref<Boolean>();
    final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
    if (indicator != null) {
      indicator.setText(SvnBundle.message("progress.text2.collecting.history", path.getName()));
    }
    final Consumer<VcsFileRevision> consumer =
        new Consumer<VcsFileRevision>() {
          public void consume(VcsFileRevision vcsFileRevision) {
            if (!Boolean.TRUE.equals(sessionReported.get())) {
              partner.reportCreatedEmptySession(historySession);
              sessionReported.set(true);
            }
            partner.acceptRevision(vcsFileRevision);
          }
        };

    logLoader.setConsumer(consumer);
    logLoader.load();
    logLoader.check();
  }
 @Override
 public int hashCode() {
   if (hashcode == 0) {
     hashcode = myPath != null ? myPath.hashCode() : 0;
     hashcode = 31 * hashcode + (myVcs != null ? myVcs.getName().hashCode() : 0);
   }
   return hashcode;
 }
 private static void correctListForRevision(
     final ProjectLevelVcsManager plVcsManager,
     final ContentRevision revision,
     final SVNChangelistClient client,
     final String name) {
   if (revision != null) {
     final FilePath path = revision.getFile();
     final AbstractVcs vcs = plVcsManager.getVcsFor(path);
     if (vcs != null && VCS_NAME.equals(vcs.getName())) {
       try {
         client.doAddToChangelist(new File[] {path.getIOFile()}, SVNDepth.EMPTY, name, null);
       } catch (SVNException e) {
         // left in default list
       }
     }
   }
 }
 @Override
 protected String getName(FilePath path) {
   final String module = myModules.get(path.getVirtualFile());
   if (module != null) {
     return module;
   }
   return super.getName(path);
 }
  private String getDiffWindowTitle(final Change change) {
    if (change.isMoved() || change.isRenamed()) {
      final FilePath beforeFilePath = ChangesUtil.getBeforePath(change);
      final FilePath afterFilePath = ChangesUtil.getAfterPath(change);

      final String beforePath =
          beforeFilePath == null ? "" : beforeFilePath.getIOFile().getAbsolutePath();
      final String afterPath =
          afterFilePath == null ? "" : afterFilePath.getIOFile().getAbsolutePath();
      return SvnBundle.message(
          "action.Subversion.properties.difference.diff.for.move.title", beforePath, afterPath);
    } else {
      return SvnBundle.message(
          "action.Subversion.properties.difference.diff.title",
          ChangesUtil.getFilePath(change).getIOFile().getAbsolutePath());
    }
  }
 @Override
 protected boolean approximatelyHasRoots(final VcsContext dataContext) {
   final FilePath[] paths = dataContext.getSelectedFilePaths();
   if (paths.length == 0) return false;
   final FileStatusManager fsm = FileStatusManager.getInstance(dataContext.getProject());
   for (final FilePath path : paths) {
     VirtualFile file = path.getVirtualFile();
     if (file == null) {
       continue;
     }
     FileStatus status = fsm.getStatus(file);
     if (isApplicableRoot(file, status, dataContext)) {
       return true;
     }
   }
   return false;
 }
 @NotNull
 public static SvnContentRevision createRemote(
     @NotNull SvnVcs vcs, @NotNull FilePath file, @NotNull SVNRevision revision) {
   if (file.getFileType().isBinary()) {
     return new SvnBinaryContentRevision(vcs, file, revision, false);
   }
   return new SvnContentRevision(vcs, file, revision, false);
 }
 private String modifyCheckinActionName(final VcsContext dataContext, String checkinActionName) {
   final FilePath[] roots = getRoots(dataContext);
   if (roots == null || roots.length == 0) return checkinActionName;
   final FilePath first = roots[0];
   if (roots.length == 1) {
     if (first.isDirectory()) {
       return VcsBundle.message("action.name.checkin.directory", checkinActionName);
     } else {
       return VcsBundle.message("action.name.checkin.file", checkinActionName);
     }
   } else {
     if (first.isDirectory()) {
       return VcsBundle.message("action.name.checkin.directories", checkinActionName);
     } else {
       return VcsBundle.message("action.name.checkin.files", checkinActionName);
     }
   }
 }
 @Override
 public boolean fileIsUnderVcs(FilePath path) {
   final ChangeListManager clManager = ChangeListManager.getInstance(myProject);
   final VirtualFile file = path.getVirtualFile();
   if (file == null) {
     return false;
   }
   return !SvnStatusUtil.isIgnoredInAnySense(clManager, file) && !clManager.isUnversioned(file);
 }
Beispiel #30
0
 @Override
 public SvnHistorySession createFromCachedData(
     Boolean aBoolean,
     @NotNull List<VcsFileRevision> revisions,
     @NotNull FilePath filePath,
     VcsRevisionNumber currentRevision) {
   return new SvnHistorySession(
       myVcs, revisions, filePath, aBoolean, currentRevision, false, !filePath.isNonLocal());
 }