Merge remote-tracking branch 'origin/master'

This commit is contained in:
Nadya.Zabrodina
2013-01-22 17:26:15 +04:00
16 changed files with 91 additions and 35 deletions
@@ -45,6 +45,7 @@ import javax.swing.border.Border;
import java.awt.*;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.MouseEvent;
public class DiffSideView {
private final JComponent MOCK_COMPONENT = new JPanel();
@@ -157,6 +158,9 @@ public class DiffSideView {
private final EditorMouseAdapter myMouseListener = new EditorMouseAdapter() {
public void mouseReleased(EditorMouseEvent e) {
if (e.getMouseEvent().getButton() != MouseEvent.BUTTON1) {
return;
}
if (!isInMyArea(e)) return;
OpenFileDescriptor descriptor = getOpenFileDescriptor(e);
if (descriptor == null) return;
@@ -23,15 +23,17 @@ import com.intellij.openapi.vcs.CheckoutProvider;
import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import git4idea.commands.Git;
import git4idea.GitVcs;
import git4idea.actions.BasicAction;
import git4idea.commands.Git;
import git4idea.commands.GitCommandResult;
import git4idea.commands.GitLineHandlerListener;
import git4idea.commands.GitStandardProgressAnalyzer;
import git4idea.i18n.GitBundle;
import git4idea.jgit.GitHttpAdapter;
import git4idea.util.GitUIUtil;
import git4idea.update.GitFetchResult;
import git4idea.update.GitFetcher;
import git4idea.util.GitUIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -83,7 +85,7 @@ public class GitCheckoutProvider implements CheckoutProvider {
new Task.Backgroundable(project, GitBundle.message("cloning.repository", sourceRepositoryURL)) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
cloneResult.set(doClone(project, git, directoryName, parentDirectory, sourceRepositoryURL));
cloneResult.set(doClone(project, indicator, git, directoryName, parentDirectory, sourceRepositoryURL));
}
@Override
@@ -106,20 +108,23 @@ public class GitCheckoutProvider implements CheckoutProvider {
}.queue();
}
private static boolean doClone(@NotNull Project project, @NotNull Git git, @NotNull String directoryName, @NotNull String parentDirectory,
@NotNull String sourceRepositoryURL) {
private static boolean doClone(@NotNull Project project, @NotNull ProgressIndicator indicator, @NotNull Git git,
@NotNull String directoryName, @NotNull String parentDirectory, @NotNull String sourceRepositoryURL) {
if (GitHttpAdapter.shouldUseJGit(sourceRepositoryURL)) {
GitFetchResult result = GitHttpAdapter.cloneRepository(project, new File(parentDirectory, directoryName), sourceRepositoryURL);
GitFetcher.displayFetchResult(project, result, "Clone failed", result.getErrors());
return result.isSuccess();
}
else {
return cloneNatively(project, git, new File(parentDirectory), sourceRepositoryURL, directoryName);
return cloneNatively(project, indicator, git, new File(parentDirectory), sourceRepositoryURL, directoryName);
}
}
private static boolean cloneNatively(Project project, @NotNull Git git, File directory, String url, String cloneDirectoryName) {
GitCommandResult result = git.clone(project, directory, url, cloneDirectoryName);
private static boolean cloneNatively(@NotNull Project project, @NotNull final ProgressIndicator indicator,
@NotNull Git git, @NotNull File directory, @NotNull String url, @NotNull String cloneDirectoryName) {
indicator.setIndeterminate(false);
GitLineHandlerListener progressListener = GitStandardProgressAnalyzer.createListener(indicator);
GitCommandResult result = git.clone(project, directory, url, cloneDirectoryName, progressListener);
if (result.success()) {
return true;
}
@@ -47,7 +47,8 @@ public interface Git {
@Nullable List<String> relativePaths) throws VcsException;
@NotNull
GitCommandResult clone(@NotNull Project project, @NotNull File parentDirectory, @NotNull String url, @NotNull String clonedDirectoryName);
GitCommandResult clone(@NotNull Project project, @NotNull File parentDirectory, @NotNull String url, @NotNull String clonedDirectoryName,
@NotNull GitLineHandlerListener... progressListeners);
@NotNull
GitCommandResult config(@NotNull GitRepository repository, String... params);
@@ -356,7 +356,7 @@ public abstract class GitHandler {
* @return is "--progress" parameter supported by this version of Git.
*/
public boolean addProgressParameter() {
if (GitVersionSpecialty.ABLE_TO_USE_PROGRESS.existsIn(myVcs.getVersion())) {
if (GitVersionSpecialty.ABLE_TO_USE_PROGRESS_IN_REMOTE_COMMANDS.existsIn(myVcs.getVersion())) {
addParameters("--progress");
return true;
}
@@ -131,10 +131,12 @@ public class GitImpl implements Git {
@Override
@NotNull
public GitCommandResult clone(@NotNull Project project, @NotNull File parentDirectory, @NotNull String url,
@NotNull String clonedDirectoryName) {
@NotNull String clonedDirectoryName, @NotNull GitLineHandlerListener... listeners) {
GitLineHandlerPasswordRequestAware handler = new GitLineHandlerPasswordRequestAware(project, parentDirectory, GitCommand.CLONE);
handler.addParameters("--progress");
handler.addParameters(url);
handler.addParameters(clonedDirectoryName);
addListeners(handler, listeners);
return run(handler, true);
}
@@ -361,6 +363,7 @@ public class GitImpl implements Git {
GitCommand.PUSH);
h.setSilent(false);
addListeners(h, listeners);
h.addProgressParameter();
h.addParameters(remote);
h.addParameters(spec);
return run(h, true);
@@ -15,6 +15,8 @@
*/
package git4idea.commands;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.util.Key;
import gnu.trove.TObjectDoubleHashMap;
import gnu.trove.TObjectDoubleProcedure;
@@ -32,6 +34,19 @@ public class GitStandardProgressAnalyzer implements GitProgressAnalyzer {
// but it looks simpler than storing current operation, checking that ther was no skipped, etc.
private TObjectDoubleHashMap<Operation> myOperationsProgress = new TObjectDoubleHashMap<Operation>(4);
public static GitLineHandlerListener createListener(final ProgressIndicator indicator) {
final GitStandardProgressAnalyzer progressAnalyzer = new GitStandardProgressAnalyzer();
return new GitLineHandlerAdapter() {
@Override
public void onLineAvailable(String line, Key outputType) {
final double fraction = progressAnalyzer.analyzeProgress(line);
if (fraction >= 0) {
indicator.setFraction(fraction);
}
}
};
}
/**
* A long git command usually consists of the operations in this enum.
* A pattern is used to match the operation from the git output. fraction is used to indicate which part of the total git command
@@ -52,14 +67,14 @@ public class GitStandardProgressAnalyzer implements GitProgressAnalyzer {
}
},
COMPRESSING_OBJECTS(".*Compressing objects: +(\\d{1,3})%.*", 0.1),
RECEVING_OBJECTS(".*Receiving objects: +(\\d{1,3})%.*", 0.8),
RECEIVING_OR_WRITING_OBJECTS(".*(?:Receiving|Writing) objects: +(\\d{1,3})%.*", 0.8), // receiving on fetch, writing on push
RESOLVING_DELTAS(".*Resolving deltas: +(\\d{1,3})%.*", 0.05);
private Pattern myPattern;
private double myFractionInTotal;
Operation(String pattern, double fractionInTotal) {
myPattern = Pattern.compile(pattern);
myPattern = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE);
myFractionInTotal = fractionInTotal;
}
@@ -37,11 +37,10 @@ import org.jetbrains.annotations.NotNull;
public enum GitVersionSpecialty {
/**
* This version of git has "--progress" parameter in long-going commands (such as clone or fetch).
* Note that while pull, clone and fetch received the parameter since 1.7.1.1,
* some other commands (like merge) might have achieved it later.
* This version of git has "--progress" parameter in long-going remote commands: clone, fetch, pull, push.
* Note that other commands (like merge) don't have this parameter in this version yet.
*/
ABLE_TO_USE_PROGRESS {
ABLE_TO_USE_PROGRESS_IN_REMOTE_COMMANDS {
@Override
public boolean existsIn(@NotNull GitVersion version) {
return version.isLaterOrEqual(new GitVersion(1, 7, 1, 1));
@@ -157,6 +157,9 @@ public class GitPullDialog extends DialogWrapper {
GitLineHandler h = new GitLineHandler(myProject, gitRoot(), pull ? GitCommand.PULL : GitCommand.MERGE);
// ignore merge failure for the pull
h.ignoreErrorCode(1);
if (pull) {
h.addProgressParameter();
}
h.addParameters("--no-stat");
if (myNoCommitCheckBox.isSelected()) {
h.addParameters("--no-commit");
@@ -31,6 +31,8 @@ import git4idea.*;
import git4idea.branch.GitBranchPair;
import git4idea.commands.Git;
import git4idea.commands.GitCommandResult;
import git4idea.commands.GitLineHandlerListener;
import git4idea.commands.GitStandardProgressAnalyzer;
import git4idea.config.GitConfigUtil;
import git4idea.config.GitVcsSettings;
import git4idea.config.UpdateMethod;
@@ -396,7 +398,8 @@ public final class GitPusher {
@NotNull
private GitSimplePushResult pushNatively(GitRepository repository, GitPushSpec pushSpec) {
GitPushRejectedDetector rejectedDetector = new GitPushRejectedDetector();
GitCommandResult res = myGit.push(repository, pushSpec, rejectedDetector);
GitLineHandlerListener progressListener = GitStandardProgressAnalyzer.createListener(myProgressIndicator);
GitCommandResult res = myGit.push(repository, pushSpec, rejectedDetector, progressListener);
if (rejectedDetector.rejected()) {
Collection<String> rejectedBranches = rejectedDetector.getRejectedBranches();
return GitSimplePushResult.reject(rejectedBranches);
@@ -39,23 +39,24 @@ public class GitRepositoryManagerImpl extends AbstractProjectComponent implement
private static final Logger LOG = Logger.getInstance(GitRepositoryManager.class);
@NotNull private final AbstractVcs myVcs;
@NotNull private final ProjectLevelVcsManager myVcsManager;
@NotNull private AbstractVcs myVcs;
@NotNull private final Map<VirtualFile, GitRepository> myRepositories = new HashMap<VirtualFile, GitRepository>();
@NotNull private final ReentrantReadWriteLock REPO_LOCK = new ReentrantReadWriteLock();
@NotNull private final GitPlatformFacade myPlatformFacade;
public GitRepositoryManagerImpl(@NotNull Project project, @NotNull GitPlatformFacade platformFacade) {
public GitRepositoryManagerImpl(@NotNull Project project, @NotNull GitPlatformFacade platformFacade,
@NotNull ProjectLevelVcsManager vcsManager) {
super(project);
myPlatformFacade = platformFacade;
myVcsManager = ProjectLevelVcsManager.getInstance(myProject);
myVcs = platformFacade.getVcs(myProject);
myVcsManager = vcsManager;
}
@Override
public void initComponent() {
myVcs = myPlatformFacade.getVcs(myProject);
Disposer.register(myProject, this);
myProject.getMessageBus().connect().subscribe(ProjectLevelVcsManager.VCS_CONFIGURATION_CHANGED, this);
GitRootScanner rootScanner = new GitRootScanner(myProject);
@@ -211,6 +211,7 @@ public class GitFetcher {
private GitFetchResult fetchNatively(@NotNull VirtualFile root, @NotNull GitRemote remote, @Nullable String branch) {
final GitLineHandlerPasswordRequestAware h = new GitLineHandlerPasswordRequestAware(myProject, root, GitCommand.FETCH);
h.addProgressParameter();
if (GitVersionSpecialty.SUPPORTS_FETCH_PRUNE.existsIn(myVcs.getVersion())) {
h.addParameters("--prune");
}
@@ -221,7 +222,7 @@ public class GitFetcher {
h.addParameters(getFetchSpecForBranch(branch, remoteName));
}
final GitTask fetchTask = new GitTask(myProject, h, "Fetching...");
final GitTask fetchTask = new GitTask(myProject, h, "Fetching " + remote.getFirstUrl());
fetchTask.setProgressIndicator(myProgressIndicator);
fetchTask.setProgressAnalyzer(new GitStandardProgressAnalyzer());
@@ -76,7 +76,8 @@ public class GitMergeUpdater extends GitUpdater {
GitUntrackedFilesOverwrittenByOperationDetector untrackedFilesDetector = new GitUntrackedFilesOverwrittenByOperationDetector(myRoot);
mergeHandler.addLineListener(untrackedFilesDetector);
final GitTask mergeTask = new GitTask(myProject, mergeHandler, "Merging changes");
String progressTitle = makeProgressTitle("Merging");
final GitTask mergeTask = new GitTask(myProject, mergeHandler, progressTitle);
mergeTask.setProgressIndicator(myProgressIndicator);
mergeTask.setProgressAnalyzer(new GitStandardProgressAnalyzer());
final AtomicReference<GitUpdateResult> updateResult = new AtomicReference<GitUpdateResult>();
@@ -73,7 +73,8 @@ public class GitRebaseUpdater extends GitUpdater {
GitUntrackedFilesOverwrittenByOperationDetector untrackedFilesDetector = new GitUntrackedFilesOverwrittenByOperationDetector(myRoot);
rebaseHandler.addLineListener(untrackedFilesDetector);
GitTask rebaseTask = new GitTask(myProject, rebaseHandler, "Rebasing");
String progressTitle = makeProgressTitle("Rebasing");
GitTask rebaseTask = new GitTask(myProject, rebaseHandler, progressTitle);
rebaseTask.setProgressIndicator(myProgressIndicator);
rebaseTask.setProgressAnalyzer(new GitStandardProgressAnalyzer());
final AtomicReference<GitUpdateResult> updateResult = new AtomicReference<GitUpdateResult>();
@@ -24,6 +24,7 @@ import com.intellij.openapi.vcs.update.UpdatedFiles;
import com.intellij.openapi.vfs.VirtualFile;
import git4idea.GitBranch;
import git4idea.GitRevisionNumber;
import git4idea.GitUtil;
import git4idea.GitVcs;
import git4idea.branch.GitBranchPair;
import git4idea.branch.GitBranchUtil;
@@ -33,6 +34,7 @@ import git4idea.commands.GitSimpleHandler;
import git4idea.config.GitConfigUtil;
import git4idea.config.GitVcsSettings;
import git4idea.merge.MergeChangeCollector;
import git4idea.repo.GitRepositoryManager;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
@@ -48,11 +50,12 @@ public abstract class GitUpdater {
@NotNull protected final Project myProject;
@NotNull protected final Git myGit;
protected final @NotNull VirtualFile myRoot;
protected final @NotNull Map<VirtualFile, GitBranchPair> myTrackedBranches;
protected final @NotNull ProgressIndicator myProgressIndicator;
protected final @NotNull UpdatedFiles myUpdatedFiles;
protected final @NotNull AbstractVcsHelper myVcsHelper;
@NotNull protected final VirtualFile myRoot;
@NotNull protected final Map<VirtualFile, GitBranchPair> myTrackedBranches;
@NotNull protected final ProgressIndicator myProgressIndicator;
@NotNull protected final UpdatedFiles myUpdatedFiles;
@NotNull protected final AbstractVcsHelper myVcsHelper;
@NotNull protected final GitRepositoryManager myRepositoryManager;
protected final GitVcs myVcs;
protected GitRevisionNumber myBefore; // The revision that was before update
@@ -68,6 +71,7 @@ public abstract class GitUpdater {
myUpdatedFiles = updatedFiles;
myVcsHelper = AbstractVcsHelper.getInstance(project);
myVcs = GitVcs.getInstance(project);
myRepositoryManager = GitUtil.getRepositoryManager(myProject);
}
/**
@@ -174,4 +178,10 @@ public abstract class GitUpdater {
String output = handler.run();
return output != null && !output.isEmpty();
}
@NotNull
protected String makeProgressTitle(@NotNull String operation) {
return myRepositoryManager.moreThanOneRoot() ? String.format("%s %s...", operation, myRoot.getName()) : operation + "...";
}
}
@@ -74,7 +74,7 @@ public class GitTestImpl implements Git {
public GitCommandResult clone(@NotNull Project project,
@NotNull File parentDirectory,
@NotNull String url,
@NotNull String clonedDirectoryName) {
@NotNull String clonedDirectoryName, @NotNull GitLineHandlerListener... progressListeners) {
throw new UnsupportedOperationException();
}
@@ -16,8 +16,8 @@
package git4idea.tests;
import git4idea.commands.GitStandardProgressAnalyzer;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.junit.Before;
import org.junit.Test;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@@ -32,7 +32,7 @@ public class GitStandardProgressAnalyzerTest {
private static final double EPS = 0.00001;
private GitStandardProgressAnalyzer myProgressModifier;
@BeforeMethod
@Before
public void setUp() {
myProgressModifier = new GitStandardProgressAnalyzer();
}
@@ -54,8 +54,16 @@ public class GitStandardProgressAnalyzerTest {
@Test
public void recevingObjects() {
assertEquals(myProgressModifier.analyzeProgress("remote: Receiving objects: 70% (595/850), 4.18 MiB | 223 KiB/s"), 0.15 + 0.8 * 0.7, EPS);
assertEquals(myProgressModifier.analyzeProgress("remote: Receiving objects: 70% (595/850), 4.18 MiB | 223 KiB/s"),
0.15 + 0.8 * 0.7, EPS);
}
@Test
public void writingObjects() {
assertEquals(myProgressModifier.analyzeProgress("Writing objects: 60% (3/5), 49.91 MiB | 422 KiB/s"),
0.15 + 0.8 * 0.6, EPS);
}
@Test
public void resolvingDeltas() {
assertEquals(myProgressModifier.analyzeProgress("remote: Resolving deltas: 34% (289/850)"), 0.95 + 0.05 * 0.34, EPS);
@@ -99,6 +107,7 @@ public class GitStandardProgressAnalyzerTest {
}
}
Object resolvingDeltasOperation = null;
assert operationClass != null;
for (Object enumConstant : operationClass.getEnumConstants()) {
if (enumConstant.toString() == "RESOLVING_DELTAS") {
resolvingDeltasOperation = enumConstant;