/** * Update index (delete and remove files) * * @param project the project * @param root a vcs root * @param added added/modified files to commit * @param removed removed files to commit * @param exceptions a list of exceptions to update * @return true if index was updated successfully */ private static boolean updateIndex( final Project project, final VirtualFile root, final Collection<FilePath> added, final Collection<FilePath> removed, final List<VcsException> exceptions) { boolean rc = true; if (!added.isEmpty()) { try { GitFileUtils.addPaths(project, root, added); } catch (VcsException ex) { exceptions.add(ex); rc = false; } } if (!removed.isEmpty()) { try { GitFileUtils.delete(project, root, removed, "--ignore-unmatch"); } catch (VcsException ex) { exceptions.add(ex); rc = false; } } return rc; }
/** {@inheritDoc} */ public List<VcsException> scheduleUnversionedFilesForAddition(List<VirtualFile> files) { ArrayList<VcsException> rc = new ArrayList<VcsException>(); Map<VirtualFile, List<VirtualFile>> sortedFiles; try { sortedFiles = GitUtil.sortFilesByGitRoot(files); } catch (VcsException e) { rc.add(e); return rc; } for (Map.Entry<VirtualFile, List<VirtualFile>> e : sortedFiles.entrySet()) { try { final VirtualFile root = e.getKey(); GitFileUtils.addFiles(myProject, root, e.getValue()); markRootDirty(root); } catch (VcsException ex) { rc.add(ex); } } return rc; }
public List<VcsException> commit( @NotNull List<Change> changes, @NotNull String message, @NotNull NullableFunction<Object, Object> parametersHolder, Set<String> feedback) { List<VcsException> exceptions = new ArrayList<VcsException>(); Map<VirtualFile, Collection<Change>> sortedChanges = sortChangesByGitRoot(changes, exceptions); log.assertTrue( !sortedChanges.isEmpty(), "Trying to commit an empty list of changes: " + changes); for (Map.Entry<VirtualFile, Collection<Change>> entry : sortedChanges.entrySet()) { final VirtualFile root = entry.getKey(); try { File messageFile = createMessageFile(root, message); try { final Set<FilePath> added = new HashSet<FilePath>(); final Set<FilePath> removed = new HashSet<FilePath>(); for (Change change : entry.getValue()) { switch (change.getType()) { case NEW: case MODIFICATION: added.add(change.getAfterRevision().getFile()); break; case DELETED: removed.add(change.getBeforeRevision().getFile()); break; case MOVED: FilePath afterPath = change.getAfterRevision().getFile(); FilePath beforePath = change.getBeforeRevision().getFile(); added.add(afterPath); if (!GitFileUtils.shouldIgnoreCaseChange( afterPath.getPath(), beforePath.getPath())) { removed.add(beforePath); } break; default: throw new IllegalStateException("Unknown change type: " + change.getType()); } } try { try { Set<FilePath> files = new HashSet<FilePath>(); files.addAll(added); files.addAll(removed); commit( myProject, root, files, messageFile, myNextCommitAuthor, myNextCommitAmend, myNextCommitAuthorDate); } catch (VcsException ex) { PartialOperation partialOperation = isMergeCommit(ex); if (partialOperation == PartialOperation.NONE) { throw ex; } if (!mergeCommit( myProject, root, added, removed, messageFile, myNextCommitAuthor, exceptions, partialOperation)) { throw ex; } } } finally { if (!messageFile.delete()) { log.warn("Failed to remove temporary file: " + messageFile); } } } catch (VcsException e) { exceptions.add(e); } } catch (IOException ex) { //noinspection ThrowableInstanceNeverThrown exceptions.add(new VcsException("Creation of commit message file failed", ex)); } } if (myNextCommitIsPushed != null && myNextCommitIsPushed.booleanValue() && exceptions.isEmpty()) { // push UIUtil.invokeLaterIfNeeded( new Runnable() { public void run() { GitPusher.showPushDialogAndPerformPush( myProject, ServiceManager.getService(myProject, GitPlatformFacade.class)); } }); } return exceptions; }
@Override public void after(@NotNull List<? extends VFileEvent> events) { // which files in .git were changed boolean configChanged = false; boolean headChanged = false; boolean branchFileChanged = false; boolean packedRefsChanged = false; boolean rebaseFileChanged = false; boolean mergeFileChanged = false; for (VFileEvent event : events) { final VirtualFile file = event.getFile(); if (file == null) { continue; } String filePath = GitFileUtils.stripFileProtocolPrefix(file.getPath()); if (myRepositoryFiles.isConfigFile(filePath)) { configChanged = true; } else if (myRepositoryFiles.isHeadFile(filePath)) { headChanged = true; } else if (myRepositoryFiles.isBranchFile(filePath)) { // it is also possible, that a local branch with complex name ("myfolder/mybranch") was // created => the folder also to be watched. branchFileChanged = true; visitAllChildrenRecursively(myHeadsDir); } else if (myRepositoryFiles.isRemoteBranchFile(filePath)) { // it is possible, that a branch from a new remote was fetch => we need to add new remote // folder to the VFS branchFileChanged = true; visitAllChildrenRecursively(myRemotesDir); } else if (myRepositoryFiles.isPackedRefs(filePath)) { packedRefsChanged = true; } else if (myRepositoryFiles.isRebaseFile(filePath)) { rebaseFileChanged = true; } else if (myRepositoryFiles.isMergeFile(filePath)) { mergeFileChanged = true; } } // what should be updated in GitRepository boolean updateCurrentBranch = false; boolean updateCurrentRevision = false; boolean updateState = false; boolean updateBranches = false; if (headChanged) { updateCurrentBranch = true; updateCurrentRevision = true; updateState = true; } if (branchFileChanged) { updateCurrentRevision = true; updateBranches = true; } if (rebaseFileChanged || mergeFileChanged) { updateState = true; } if (packedRefsChanged) { updateCurrentBranch = true; updateBranches = true; } // update GitRepository on pooled thread, because it requires reading from disk and parsing // data. if (updateCurrentBranch) { myUpdateQueue.add(GitRepository.TrackedTopic.CURRENT_BRANCH); } if (updateCurrentRevision) { myUpdateQueue.add(GitRepository.TrackedTopic.CURRENT_REVISION); } if (updateState) { myUpdateQueue.add(GitRepository.TrackedTopic.STATE); } if (updateBranches) { myUpdateQueue.add(GitRepository.TrackedTopic.BRANCHES); } if (configChanged) { myUpdateQueue.add(GitRepository.TrackedTopic.CONFIG); } }
public synchronized byte[] loadContent() throws IOException, VcsException { final VirtualFile root = GitUtil.getGitRoot(path); return GitFileUtils.getFileContent( project, root, revision.getRev(), VcsFileUtil.relativePath(root, path)); }
private static boolean performFirstCommitIfRequired( @NotNull final Project project, @NotNull VirtualFile root, @NotNull GitRepository repository, @NotNull ProgressIndicator indicator, @NotNull String name, @NotNull String url) { // check if there is no commits if (!repository.isFresh()) { return true; } LOG.info("Trying to commit"); try { LOG.info("Adding files for commit"); indicator.setText("Adding files to git..."); // ask for files to add final List<VirtualFile> trackedFiles = ChangeListManager.getInstance(project).getAffectedFiles(); final Collection<VirtualFile> untrackedFiles = filterOutIgnored(project, repository.getUntrackedFilesHolder().retrieveUntrackedFiles()); trackedFiles.removeAll(untrackedFiles); // fix IDEA-119855 final List<VirtualFile> allFiles = new ArrayList<VirtualFile>(); allFiles.addAll(trackedFiles); allFiles.addAll(untrackedFiles); final Ref<GithubUntrackedFilesDialog> dialogRef = new Ref<GithubUntrackedFilesDialog>(); ApplicationManager.getApplication() .invokeAndWait( new Runnable() { @Override public void run() { GithubUntrackedFilesDialog dialog = new GithubUntrackedFilesDialog(project, allFiles); if (!trackedFiles.isEmpty()) { dialog.setSelectedFiles(trackedFiles); } DialogManager.show(dialog); dialogRef.set(dialog); } }, indicator.getModalityState()); final GithubUntrackedFilesDialog dialog = dialogRef.get(); final Collection<VirtualFile> files2commit = dialog.getSelectedFiles(); if (!dialog.isOK() || files2commit.isEmpty()) { GithubNotifications.showInfoURL( project, "Successfully created empty repository on GitHub", name, url); return false; } Collection<VirtualFile> files2add = ContainerUtil.intersection(untrackedFiles, files2commit); Collection<VirtualFile> files2rm = ContainerUtil.subtract(trackedFiles, files2commit); Collection<VirtualFile> modified = new HashSet<VirtualFile>(trackedFiles); modified.addAll(files2commit); GitFileUtils.addFiles(project, root, files2add); GitFileUtils.deleteFilesFromCache(project, root, files2rm); // commit LOG.info("Performing commit"); indicator.setText("Performing commit..."); GitSimpleHandler handler = new GitSimpleHandler(project, root, GitCommand.COMMIT); handler.addParameters("-m", dialog.getCommitMessage()); handler.endOptions(); handler.run(); VcsFileUtil.refreshFiles(project, modified); } catch (VcsException e) { LOG.warn(e); GithubNotifications.showErrorURL( project, "Can't finish GitHub sharing process", "Successfully created project ", "'" + name + "'", " on GitHub, but initial commit failed:<br/>" + GithubUtil.getErrorTextFromException(e), url); return false; } LOG.info("Successfully created initial commit"); return true; }