diff --git a/plugins/git4idea/test-features/git4idea/cherry-pick-without-auto-commit.feature b/plugins/git4idea/test-features/git4idea/cherry-pick-without-auto-commit.feature
new file mode 100644
index 000000000000..715f9e268720
--- /dev/null
+++ b/plugins/git4idea/test-features/git4idea/cherry-pick-without-auto-commit.feature
@@ -0,0 +1,144 @@
+Feature: Git Cherry-Pick When Auto-Commit is deselected
+
+ Background:
+ Given disabled auto-commit in the settings
+ Given new committed files file.txt, a.txt, conflict.txt with initial content
+ Given branch feature
+
+ Given commit f5027a3 on branch feature
+ """
+ fix #1
+ Author: John Bro
+ M file.txt "feature changes"
+ """
+
+ Scenario: Simple cherry-pick
+ When I cherry-pick the commit f5027a3
+ Then commit dialog should be shown
+ And active changelist is 'fix #1 (cherry picked from commit f5027a3)'
+
+
+ Scenario: Simple cherry-pick, agree to commit
+ When I cherry-pick the commit f5027a3 and commit
+ Then the last commit is
+ """
+ fix #1
+ (cherry picked from commit f5027a3)
+ """
+ And success notification is shown 'Cherry-pick successful'
+ """
+ f5027a3 fix #1
+ """
+ And no new changelists are created
+
+ Scenario: Simple cherry-pick, cancel commit
+ When I cherry-pick the commit f5027a3 and don't commit
+ Then nothing is committed
+ And active changelist is 'fix #1 (cherry picked from commit f5027a3)'
+ And no notification is shown
+
+ Scenario: Cherry-pick 2 commits
+ Given commit abc1234 on branch feature
+ """
+ fix #2
+ M file.txt "more feature changes"
+ """
+ When I cherry-pick commits f5027a3, abc1234 and commit both of them
+ Then `git log -2` should return
+ """
+ fix #2
+ (cherry picked from commit abc1234)
+ -----
+ fix #1
+ (cherry picked from commit f5027a3)
+ """
+ And no new changelists are created
+
+ Scenario: Cherry-pick 2 commits, cancel committing the second
+ Given commit abc1234 on branch feature
+ """
+ fix #2
+ M file.txt "more feature changes"
+ """
+ When I cherry-pick commits f5027a3, abc1234, but commit only the first one
+ Then the last commit is
+ """
+ fix #1
+ (cherry picked from commit f5027a3)
+ """
+ And working tree is dirty
+ And active changelist is 'fix #2 (cherry picked from commit abc1234)'
+ And warning notification is shown 'Cherry-pick cancelled'
+ """
+ abc1234 fix #2
+
+ However cherry-pick succeeded for the following commit:
+ f5027a3 fix #1
+ """
+
+ Scenario: Dirty tree, conflicting with the commit
+ Given file.txt is locally modified:
+ """
+ master content
+ """
+ When I cherry-pick the commit f5027a3
+ Then nothing is committed
+ And error notification is shown 'Cherry-pick failed'
+ """
+ f5027a3 fix #1
+ Your local changes would be overwritten by cherry-pick.
+ Commit your changes or stash them to proceed.
+ """
+
+ Scenario: Untracked files, conflicting with cherry-picked commit
+ Given commit aff6453 on branch feature
+ """
+ add file
+ A untracked.txt "feature changes"
+ """
+ Given file untracked.txt 'master changes'
+ When I cherry-pick the commit aff6453
+ Then no new changelists are created
+ And error notification is shown 'Cherry-pick failed'
+ """
+ aff6453 add file
+ Some untracked working tree files would be overwritten by cherry-pick.
+ Please move, remove or add them before you can cherry-pick. View them
+ """
+
+ Scenario: Conflict with cherry-picked commit should show merge dialog
+ Given commit aff6453 on branch master
+ """
+ master content
+ M conflict.txt "master version"
+ """
+ Given commit bb6453c on branch feature
+ """
+ feature content
+ M conflict.txt "feature version"
+ """
+ When I cherry-pick the commit bb6453c
+ Then merge dialog should be shown
+
+ Scenario: Resolve conflict and agree to commit
+ Given commit aff6453 on branch master
+ """
+ master content
+ M conflict.txt "master version"
+ """
+ Given commit bb6453c on branch feature
+ """
+ feature content
+ M conflict.txt "feature version"
+ """
+ When I cherry-pick the commit bb6453c, resolve conflicts and commit
+ Then the last commit is
+ """
+ feature content
+ (cherry picked from commit bb6453c)
+ """
+ And success notification is shown 'Cherry-pick successful'
+ """
+ bb6453c feature content
+ """
+ And no new changelists are created
diff --git a/plugins/git4idea/test-stepdefs/git4idea/GeneralStepdefs.java b/plugins/git4idea/test-stepdefs/git4idea/GeneralStepdefs.java
index 4b6f8540163a..3a4ee1f35a35 100644
--- a/plugins/git4idea/test-stepdefs/git4idea/GeneralStepdefs.java
+++ b/plugins/git4idea/test-stepdefs/git4idea/GeneralStepdefs.java
@@ -141,8 +141,13 @@ public class GeneralStepdefs {
git("commit -m 'adding files with initial content'");
}
- private static List splitByComma(String listOfFiles) {
- return Arrays.asList(listOfFiles.split(", ?"));
+ public static List splitByComma(String listOfItems) {
+ return Arrays.asList(listOfItems.split(", ?"));
+ }
+
+ @Given("^branch (.+)$")
+ public void branch(String branchName) throws Throwable {
+ git("branch " + branchName);
}
}
diff --git a/plugins/git4idea/test-stepdefs/git4idea/GitCherryPickStepdefs.java b/plugins/git4idea/test-stepdefs/git4idea/GitCherryPickStepdefs.java
index 91a6d585c022..d9a2dfd6bcb4 100644
--- a/plugins/git4idea/test-stepdefs/git4idea/GitCherryPickStepdefs.java
+++ b/plugins/git4idea/test-stepdefs/git4idea/GitCherryPickStepdefs.java
@@ -61,7 +61,7 @@ public class GitCherryPickStepdefs {
cherryPick(hash);
}
- @When("^I cherry-pick commits (.+) and (.+)$")
+ @When("^I cherry-pick commits (.+) and (\\w+)$")
public void I_cherry_pick_commits(String severalCommits, String hash2) throws Throwable {
String[] hashes = severalCommits.split(",");
@@ -73,28 +73,6 @@ public class GitCherryPickStepdefs {
cherryPick(allHashes);
}
- private static void cherryPick(String... virtualHashes) {
- List commits = new ArrayList();
- for (String virtualHash : virtualHashes) {
- commits.add(createMockCommit(virtualHash));
- }
- new GitCherryPicker(myProject, myGit, myPlatformFacade, mySettings.isAutoCommitOnCherryPick())
- .cherryPick(Collections.singletonMap(myRepository, commits));
- }
-
- private static GitCommit createMockCommit(String virtualHash) {
- CommitDetails realCommit = virtualCommits.getRealCommit(virtualHash);
- return mockCommit(realCommit.getHash(), realCommit.getMessage());
- }
-
- private static GitCommit mockCommit(String hash, String message) {
- AbstractHash ahash = AbstractHash.create(hash);
- List changes = new ArrayList();
- changes.add(new Change(null, new MockContentRevision(new FilePathImpl(new MockVirtualFile("name")), VcsRevisionNumber.NULL)));
- return new GitCommit(NullVirtualFile.INSTANCE, ahash, SHAHash.emulate(ahash), "John Smith", null, null, message, message,
- null, null, null, null, null, null, null, changes, 0);
- }
-
@When("^I cherry-pick the commit (\\w+) and( don't)? resolve conflicts$")
public void I_cherry_pick_the_commit_and_resolve_conflicts(String hash, String negation) throws Throwable {
if (negation == null) {
@@ -112,16 +90,27 @@ public class GitCherryPickStepdefs {
});
}
- private static void commitInFuture() {
+ private static void commitInFuture(final int times) {
myVcsHelper.registerHandler(new MockVcsHelper.CommitHandler() {
+
+ private int myCommitRequests;
+
@Override
public boolean commit(String commitMessage) {
+ if (myCommitRequests >= times) {
+ return false;
+ }
+ myCommitRequests++;
git(String.format("commit -am '%s'", commitMessage));
return true;
}
});
}
+ private static void commitInFuture() {
+ commitInFuture(Integer.MAX_VALUE);
+ }
+
@When("^I cherry-pick the commit (.+), resolve conflicts and( don't)? commit$")
public void I_cherry_pick_the_commit_resolve_conflicts_and_commit(String hash, String negation) throws Throwable {
resolveConflictsInFuture();
@@ -131,6 +120,26 @@ public class GitCherryPickStepdefs {
cherryPick(hash);
}
+ @When("^I cherry-pick the commit (\\w+) and( don't)? commit$")
+ public void I_cherry_pick_the_commit_hash_and_commit(String hash, String negation) throws Throwable {
+ if (negation == null) {
+ commitInFuture();
+ }
+ cherryPick(hash);
+ }
+
+ @When("^I cherry-pick commits (.+) and commit both of them$")
+ public void I_cherry_pick_commits_and_commit_both_of_them(String listOfHashes) throws Throwable {
+ commitInFuture();
+ cherryPick(GeneralStepdefs.splitByComma(listOfHashes));
+ }
+
+ @When("^I cherry-pick commits (.+), but commit only the first one$")
+ public void I_cherry_pick_commits_but_commit_only_the_first_one(String listOfHashes) throws Throwable {
+ commitInFuture(1);
+ cherryPick(GeneralStepdefs.splitByComma(listOfHashes));
+ }
+
@Then("^the last commit is$")
public void the_last_commit_is(String message) throws Throwable {
git_log_should_return(1, message);
@@ -172,8 +181,13 @@ public class GitCherryPickStepdefs {
}
@Then("^nothing is committed$")
- public void nothing_is_committed() {
- assertFalse("Working tree is unexpectedly clean", git("diff").trim().isEmpty());
+ public void nothing_is_committed() throws Throwable {
+ working_tree_is_dirty();
+ }
+
+ @And("^working tree is dirty$")
+ public void working_tree_is_dirty() throws Throwable {
+ assertFalse("Working tree is unexpectedly clean", git("diff").trim().isEmpty() && git("diff --cached").trim().isEmpty());
}
@Then("^merge dialog should be shown$")
@@ -212,9 +226,30 @@ public class GitCherryPickStepdefs {
assertEquals("Wrong active changelist", name, myChangeListManager.getDefaultChangeList().getName());
}
- @Given("^branch (.+)$")
- public void branch(String branchName) throws Throwable {
- git("branch " + branchName);
+ private static void cherryPick(List virtualHashes) {
+ List commits = new ArrayList();
+ for (String virtualHash : virtualHashes) {
+ commits.add(createMockCommit(virtualHash));
+ }
+ new GitCherryPicker(myProject, myGit, myPlatformFacade, mySettings.isAutoCommitOnCherryPick())
+ .cherryPick(Collections.singletonMap(myRepository, commits));
+ }
+
+ private static void cherryPick(String... virtualHashes) {
+ cherryPick(Arrays.asList(virtualHashes));
+ }
+
+ private static GitCommit createMockCommit(String virtualHash) {
+ CommitDetails realCommit = virtualCommits.getRealCommit(virtualHash);
+ return mockCommit(realCommit.getHash(), realCommit.getMessage());
+ }
+
+ private static GitCommit mockCommit(String hash, String message) {
+ AbstractHash ahash = AbstractHash.create(hash);
+ List changes = new ArrayList();
+ changes.add(new Change(null, new MockContentRevision(new FilePathImpl(new MockVirtualFile("name")), VcsRevisionNumber.NULL)));
+ return new GitCommit(NullVirtualFile.INSTANCE, ahash, SHAHash.emulate(ahash), "John Smith", null, null, message, message,
+ null, null, null, null, null, null, null, changes, 0);
}
}
\ No newline at end of file
diff --git a/plugins/git4idea/tests/git4idea/cherrypick/GitAutoCommittingCherryPickTest.groovy b/plugins/git4idea/tests/git4idea/cherrypick/GitAutoCommittingCherryPickTest.groovy
deleted file mode 100644
index 293a48392cea..000000000000
--- a/plugins/git4idea/tests/git4idea/cherrypick/GitAutoCommittingCherryPickTest.groovy
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * Copyright 2000-2012 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package git4idea.cherrypick
-
-import com.intellij.notification.NotificationType
-
-import git4idea.history.browser.GitCommit
-import org.junit.Before
-import org.junit.Test
-
-import static git4idea.test.MockGit.*
-import static git4idea.test.MockGit.OperationName.CHERRY_PICK
-import static git4idea.test.MockGit.OperationName.GET_UNMERGED_FILES
-import static junit.framework.Assert.assertTrue
-import git4idea.history.browser.GitCherryPicker
-
-/**
- * Cherry-pick of one or multiple commits with "commit at once" option enabled.
- *
- * @author Kirill Likhodedov
- */
-class GitAutoCommittingCherryPickTest extends GitCherryPickTest {
-
- public static final String EMPTY_CHERRY_PICK = """
-# On branch master
-# Your branch is ahead of 'origin/master' by 11 commits.
-#
-# Untracked files:
-# (use "git add ..." to include in what will be committed)
-#
-#\t.idea/
-#\tlocal_staged.patch
-#\tout/
-nothing added to commit but untracked files present (use "git add" to track)
-The previous cherry-pick is now empty, possibly due to conflict resolution.
-If you wish to commit it anyway, use:
-
- git commit --allow-empty
-
-Otherwise, please use 'git reset'
-"""
-
- @Before
- void setUp() {
- super.setUp()
- myCherryPicker = new GitCherryPicker(myProject, myGit, myPlatformFacade, true)
- }
-
- @Test
- void "clean tree, no conflicts, then commit & notify, no new changelists"() {
- GitCommit commit = commit()
-
- myGit.registerOperationExecutors(new SuccessfulCherryPickExecutor(myRepository, commit))
- invokeCherryPick(commit)
-
- assertHeadCommit(commit)
- assertOnlyDefaultChangelist()
- assertNotificationShown("Cherry-pick successful", commitDetails(commit), NotificationType.INFORMATION)
- }
-
- @Test
- void "dirty tree, conflicting with commit, then show error"() {
- myGit.registerOperationExecutors(new SimpleErrorOperationExecutor(CHERRY_PICK, LOCAL_CHANGES_OVERWRITTEN_BY_CHERRY_PICK))
-
- def commit = commit()
- invokeCherryPick(commit)
-
- assertNotCherryPicked()
- assertOnlyDefaultChangelist()
- assertNotificationShown("Cherry-pick failed",
- """
- ${commitDetails(commit)}
- Your local changes would be overwritten by cherry-pick.
- Commit your changes or stash them to proceed.
- """,
- NotificationType.ERROR)
- }
-
- @Test
- void "untracked files, conflicting with commit, then show error"() {
- myGit.registerOperationExecutors(new SimpleErrorOperationExecutor(CHERRY_PICK, UNTRACKED_FILES_OVERWRITTEN_BY_CHERRY_PICK))
-
- def commit = commit()
- invokeCherryPick(commit)
-
- assertNotCherryPicked()
- assertOnlyDefaultChangelist()
- assertNotificationShown("Cherry-pick error",
- """
- ${commitDetails(commit)}
- Some untracked working tree files would be overwritten by cherry-pick.
- Please move, remove or add them before you can cherry-pick. View them
- """,
- NotificationType.ERROR)
- }
-
- @Test
- void "conflict, merge dialog, not all merged, then new & active changelist, notification"() {
- prepareConflict()
- myGit.registerOperationExecutors(new SimpleSuccessOperationExecutor(GET_UNMERGED_FILES, UNMERGED_FILE))
- GitCommit commit = commit()
- invokeCherryPick(commit)
- assertMergeDialogShown()
- assertChangeLists([DEFAULT, newCommitMessage(commit)], newCommitMessage(commit))
- assertNotificationShown "Cherry-picked with conflicts",
- """
- ${commitDetails(commit)}
- Unresolved conflicts remain in the working tree. Resolve them.
- """,
- NotificationType.WARNING
- }
-
- @Test
- void "conflict, merge completed, then commit dialog"() {
- prepareConflict()
- GitCommit commit = commit()
-
- OKCommitDialogHandler handler = new OKCommitDialogHandler(myRepository)
- myVcsHelper.registerHandler(handler)
-
- invokeCherryPick(commit)
- assertMergeDialogShown()
- assertTrue "Commit dialog was not shown", handler.wasCommitDialogShown()
- }
-
- @Test
- void "conflict, merge finished, commit succeeded, no new changelists"() {
- prepareConflict()
-
- OKCommitDialogHandler handler = new OKCommitDialogHandler(myRepository)
- myVcsHelper.registerHandler(handler)
-
- GitCommit commit = commit()
- invokeCherryPick(commit)
- assertMergeDialogShown()
- assertHeadCommit(commit)
- assertTrue "Commit dialog was not shown", handler.wasCommitDialogShown()
- assertOnlyDefaultChangelist()
- }
-
- @Test
- void "conflict, merge ok, commit cancelled, then new & active changelist"() {
- prepareConflict()
-
- CancelCommitDialogHandler handler = new CancelCommitDialogHandler()
- myVcsHelper.registerHandler(handler)
-
- GitCommit commit = commit()
- invokeCherryPick(commit)
- assertMergeDialogShown()
- assertTrue "Commit dialog was not shown", handler.wasCommitDialogShown()
- assertChangeLists([DEFAULT, newCommitMessage(commit)], newCommitMessage(commit))
- }
-
- @Test
- void "2 commits, no problems, then commit all & notify"() {
- GitCommit commit1 = commit("First commit to cherry-pick")
- GitCommit commit2 = commit("Second commit to cherry-pick")
- myGit.registerOperationExecutors(new SuccessfulCherryPickExecutor(myRepository, commit1),
- new SuccessfulCherryPickExecutor(myRepository, commit2))
-
- invokeCherryPick([commit1, commit2])
- assertLastCommits commit2, commit1
- assertNotificationShown("Cherry-pick successful", notificationContent(commit1, commit2), NotificationType.INFORMATION)
- }
-
- @Test
- void "3 commits, 2nd cherry-pick conflicts with local, then 1st success, 2nd stop & error"() {
- GitCommit commit1 = commit("First")
- GitCommit commit2 = commit("Second")
- GitCommit commit3 = commit("Third")
-
- myGit.registerOperationExecutors(new SuccessfulCherryPickExecutor(myRepository, commit1),
- new SimpleErrorOperationExecutor(CHERRY_PICK, LOCAL_CHANGES_OVERWRITTEN_BY_CHERRY_PICK),
- new SuccessfulCherryPickExecutor(myRepository, commit3))
-
- invokeCherryPick([commit1, commit2, commit3])
-
- assertHeadCommit(commit1)
- assertNotificationShown("Cherry-pick failed",
- """
- ${commitDetails(commit2)}
- Your local changes would be overwritten by cherry-pick.
- Commit your changes or stash them to proceed.
-
- However cherry-pick succeeded for the following commit:
- ${commitDetails(commit1)}
- """, NotificationType.ERROR)
- }
-
- @Test
- void "3 commits, 2nd conflicts with committed, then 1st success, on 2nd show merge dialog"() {
- GitCommit commit1 = commit("First")
- GitCommit commit2 = commit("Second")
- GitCommit commit3 = commit("Third")
-
- myGit.registerOperationExecutors(new SuccessfulCherryPickExecutor(myRepository, commit1))
- prepareConflict()
- myGit.registerOperationExecutors(new SuccessfulCherryPickExecutor(myRepository, commit3))
-
- OKCommitDialogHandler handler = new OKCommitDialogHandler(myRepository)
- myVcsHelper.registerHandler(handler)
- invokeCherryPick([commit1, commit2, commit3])
-
- assertMergeDialogShown()
- assertTrue "Commit dialog was not shown", handler.wasCommitDialogShown()
- assertLastCommits commit3, commit2, commit1
- }
-
-// @Test
- void "Notify if changes have already been applied"() {
- // Inspired by IDEA-73548
- myGit.registerOperationExecutors(new SimpleErrorOperationExecutor(CHERRY_PICK, EMPTY_CHERRY_PICK))
-
- GitCommit commit = commit()
- invokeCherryPick(commit)
-
- assertNotCherryPicked()
- assertNotificationShown("Nothing to cherry-pick", "All changes from ${commitDetails(commit)} have already been applied",
- NotificationType.WARNING)
- }
-
-// @Test
- void "1st successful, 2nd empty (all applied), then compound notification"() {
- // Inspired by IDEA-73548
- GitCommit commit1 = commit()
- GitCommit commit2 = commit()
- myGit.registerOperationExecutors(new SuccessfulCherryPickExecutor(myRepository, commit1),
- new SimpleErrorOperationExecutor(CHERRY_PICK, EMPTY_CHERRY_PICK))
-
- invokeCherryPick([ commit1, commit2 ])
-
- assertHeadCommit(commit1)
- assertNotificationShown("Cherry-picked with problems",
-"""Successfully cherry-picked ${commitDetails(commit1)}
-Not cherry-picked ${commitDetails(commit2)} - all changes have already been applied""", NotificationType.WARNING)
- }
-
-}
diff --git a/plugins/git4idea/tests/git4idea/cherrypick/GitCherryPickTest.groovy b/plugins/git4idea/tests/git4idea/cherrypick/GitCherryPickTest.groovy
deleted file mode 100644
index a1dbce3ebcc4..000000000000
--- a/plugins/git4idea/tests/git4idea/cherrypick/GitCherryPickTest.groovy
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright 2000-2012 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package git4idea.cherrypick
-
-import com.intellij.mock.MockVirtualFile
-import com.intellij.openapi.vcs.FilePathImpl
-import com.intellij.openapi.vcs.changes.Change
-import com.intellij.openapi.vcs.changes.ChangeListManager
-import com.intellij.openapi.vcs.changes.LocalChangeList
-import com.intellij.openapi.vcs.history.VcsRevisionNumber
-import com.intellij.testFramework.vcs.MockChangeListManager
-import com.intellij.testFramework.vcs.MockContentRevision
-import git4idea.history.browser.GitCherryPicker
-import git4idea.history.browser.GitCommit
-import git4idea.history.browser.SHAHash
-import git4idea.history.wholeTree.AbstractHash
-import git4idea.test.GitFastTest
-import git4idea.test.GitLightRepository
-import git4idea.test.MockGit
-import com.intellij.dvcs.test.MockVcsHelper
-import sun.security.provider.SHA
-
-import static MockGit.OperationName.CHERRY_PICK
-import static MockGit.commitMessageForCherryPick
-import static junit.framework.Assert.assertEquals
-import static junit.framework.Assert.assertTrue
-import git4idea.test.TestNotificator
-import com.intellij.openapi.vfs.newvfs.impl.NullVirtualFile
-
-/**
- * Common parent for all tests on cherry-pick
- *
- * @author Kirill Likhodedov
- */
-class GitCherryPickTest extends GitFastTest {
-
- public static final String DEFAULT = MockChangeListManager.DEFAULT_CHANGE_LIST_NAME;
- public static final String UNMERGED_FILE = """
-100644 d87b28d6fd6e97620603e64ce70fc2f24535ec28 1\ttest.txt
-100644 7b50450f5deb7cce3b5ce92ba866f1af6e58c3c6 2\ttest.txt
-100644 a784477cdd0437a84751c52f72b971503deb48cb 3\ttest.txt
-"""
- public static final String CHERRY_PICK_CONFLICT = """
-error: could not apply ec15d8e... message
-hint: after resolving the conflicts, mark the corrected paths
-hint: with 'git add ' or 'git rm '
-hint: and commit the result with 'git commit'
-"""
- GitCherryPicker myCherryPicker
- GitLightRepository myRepository
- GitLightRepository.Commit myInitialCommit
- TestNotificator myTestNotificator
-
- static final LOCAL_CHANGES_OVERWRITTEN_BY_CHERRY_PICK =
- """
- error: Your local changes to the following files would be overwritten by merge:
- \ttest.txt
- Please, commit your changes or stash them before you can merge.
- Aborting
- """;
-
- static final UNTRACKED_FILES_OVERWRITTEN_BY_CHERRY_PICK =
- """
- error: The following untracked working tree files would be overwritten by merge:
- \tcp.txt
- Please move or remove them before you can merge.
- Aborting
- """
-
- void setUp() {
- super.setUp()
-
- myRepository = new GitLightRepository()
- myRepositoryManager.add(myRepository)
- myInitialCommit = myRepository.commit("initial")
- myTestNotificator = myPlatformFacade.getNotificator(myProject) as TestNotificator;
- }
-
- GitCommit commit(String commitMessage = "plain commit") {
- AbstractHash hash = AbstractHash.create(Integer.toHexString(new SHA().hashCode()))
- List changes = new ArrayList();
- changes.add(new Change(null, new MockContentRevision(new FilePathImpl(new MockVirtualFile("name")), VcsRevisionNumber.NULL)));
- new GitCommit(NullVirtualFile.INSTANCE, hash, SHAHash.emulate(hash), "John Smith", null, null, commitMessage, commitMessage,
- null, null, null, null, null, null, null, changes, 0)
- }
-
- void assertOnlyDefaultChangelist() {
- assertChangeLists( [DEFAULT], DEFAULT)
- }
-
- void invokeCherryPick(GitCommit commit) {
- invokeCherryPick([commit])
- }
-
- void invokeCherryPick(List commits) {
- myCherryPicker.cherryPick(Collections.singletonMap(myRepository, commits))
- }
-
- void assertHeadCommit(GitCommit commit) {
- assertEquals "Wrong commit at the HEAD", commitMessageForCherryPick(commit), myRepository.head.commitMessage
- }
-
- void assertLastCommits(GitCommit... commits) {
- GitLightRepository.Commit current = myRepository.head
- int level = 0;
- for (GitCommit commit : commits) {
- assertEquals "Wrong commit at level $level", commitMessageForCherryPick(commit), current.commitMessage
- current = current.parent
- level++;
- }
- }
-
- void assertChangeLists(Collection changeLists, String activeChangelist) {
- ChangeListManager changeListManager = myPlatformFacade.getChangeListManager(myProject)
- List lists = changeListManager.changeLists
- Collection listNames = lists.collect { it.name }
- assertEquals "Change lists are different", changeLists.toSet(), listNames.toSet()
- assertEquals "Wrong active changelist", activeChangelist, changeListManager.defaultChangeList.name
- }
-
- String commitDetails(GitCommit commit) {
- "${commit.shortHash.toString()} \"${commit.subject}\""
- }
-
- String notificationContent(GitCommit... commits) {
- commits.collect { commitDetails(it) }.join("
")
- }
-
- void assertNotCherryPicked() {
- // 1. assert not committed (i.e. git cherry-pick was not performed)
- assertNothingCommitted()
- // 2. assert working tree not changed (i.e. git cherry-pick -n was not performed either)
- assertTrue myPlatformFacade.getChangeListManager(myProject).getAllChanges().isEmpty()
- }
-
- void assertNothingCommitted() {
- assertEquals(myInitialCommit, myRepository.head)
- }
-
- void prepareConflict() {
- myGit.registerOperationExecutors(new MockGit.SimpleErrorOperationExecutor(CHERRY_PICK, CHERRY_PICK_CONFLICT),
- new MockGit.SimpleSuccessOperationExecutor(MockGit.OperationName.GET_UNMERGED_FILES, UNMERGED_FILE))
- }
-
- void assertMergeDialogShown() {
- assertTrue "Merge dialog was not shown", myVcsHelper.mergeDialogWasShown()
- }
-
- String newCommitMessage(GitCommit commit) {
- "${commit.description}\n\n(cherry-picked from ${commit.hash.value})"
- }
-
- protected static class OKCommitDialogHandler implements MockVcsHelper.CommitHandler {
-
- private final GitLightRepository myRepository;
- boolean myCommitDialogShown
-
- OKCommitDialogHandler(GitLightRepository repository) {
- myRepository = repository
- }
-
- @Override
- boolean commit(String commitMessage) {
- myCommitDialogShown = true;
- myRepository.commit(commitMessage) // answering OK in the dialog => committing
- return true;
- }
-
- boolean wasCommitDialogShown() {
- myCommitDialogShown
- }
- }
-
- protected static class CancelCommitDialogHandler implements MockVcsHelper.CommitHandler {
-
- boolean myCommitDialogShown
-
- @Override
- boolean commit(String commitMessage) {
- myCommitDialogShown = true;
- return false;
- }
-
- boolean wasCommitDialogShown() {
- myCommitDialogShown
- }
- }
-
-}
diff --git a/plugins/git4idea/tests/git4idea/cherrypick/GitNotCommittingCherryPickTest.groovy b/plugins/git4idea/tests/git4idea/cherrypick/GitNotCommittingCherryPickTest.groovy
deleted file mode 100644
index ec55fc96faf5..000000000000
--- a/plugins/git4idea/tests/git4idea/cherrypick/GitNotCommittingCherryPickTest.groovy
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright 2000-2012 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package git4idea.cherrypick
-
-import com.intellij.notification.NotificationType
-import git4idea.history.browser.GitCherryPicker
-import git4idea.history.browser.GitCommit
-import git4idea.test.GitLightRepository
-import git4idea.test.MockGit
-import com.intellij.dvcs.test.MockVcsHelper
-import org.junit.Before
-import org.junit.Test
-
-import static MockGit.OperationName.CHERRY_PICK
-import static junit.framework.Assert.*
-
-/**
- * Tests for {@link GitCherryPicker}, when the "auto-commit on cherry-pick" option is deselected.
- * Most situations are equal or similar, so the majority of cherry pick tests are located in {@link GitAutoCommittingCherryPickTest}.
- *
- * @author Kirill Likhodedov
- */
-class GitNotCommittingCherryPickTest extends GitCherryPickTest {
-
- @Before
- void setUp() {
- super.setUp()
- myCherryPicker = new GitCherryPicker(myProject, myGit, myPlatformFacade, false)
- }
-
- @Test
- void "clean tree, no conflicts, then show commit dialog, commit on ok"() {
- GitCommit commit = commit()
-
- myGit.registerOperationExecutors(new MockGit.SuccessfulCherryPickExecutor(myRepository, commit))
- OKCommitDialogHandler handler = new OKCommitDialogHandler(myRepository)
- myVcsHelper.registerHandler(handler)
-
- invokeCherryPick(commit)
-
- assertHeadCommit(commit)
- assertOnlyDefaultChangelist()
- assertTrue "Commit dialog was not shown", handler.wasCommitDialogShown()
- // notification is shown from the successful commit, can't check from here
- }
-
- @Test
- void "cancel in commit dialog shouldn't show a notification"() {
- GitCommit commit = commit()
-
- myGit.registerOperationExecutors(new MockGit.SuccessfulCherryPickExecutor(myRepository, commit))
- CancelCommitDialogHandler handler = new CancelCommitDialogHandler()
- myVcsHelper.registerHandler(handler)
-
- invokeCherryPick(commit)
-
- assertTrue "Commit dialog was not shown", handler.wasCommitDialogShown()
- assertNull "Notification should not be shown when cancelling a single commit", myTestNotificator.lastNotification
- }
-
- @Test
- void "cancel in 2nd commit dialog after successful commit should shown a notification"() {
- GitCommit commit1 = commit()
- GitCommit commit2 = commit()
-
- myGit.registerOperationExecutors(new MockGit.SimpleSuccessOperationExecutor(CHERRY_PICK, ""),
- new MockGit.SimpleSuccessOperationExecutor(CHERRY_PICK, ""))
-
- int dialogNumber = 0;
- MockVcsHelper.CommitHandler handler = new MockVcsHelper.CommitHandler() {
- boolean commit(String commitMessage) {
- dialogNumber++;
- // answer OK in the first dialog, Cancel - in the second.
- return dialogNumber == 1;
- }
- }
- myVcsHelper.registerHandler(handler)
-
- invokeCherryPick([commit1, commit2])
-
- assertEquals "Commit dialog shown wrong number of times", 2, dialogNumber
- assertNotificationShown("Cherry-pick cancelled",
- """
- ${commitDetails(commit2)}
-
- However cherry-pick succeeded for the following commit:
- ${commitDetails(commit1)}
- """, NotificationType.WARNING)
- }
-
- @Test
- void "dirty tree, conflicting with commit, then show error"() {
- myGit.registerOperationExecutors(new MockGit.SimpleErrorOperationExecutor(CHERRY_PICK, LOCAL_CHANGES_OVERWRITTEN_BY_CHERRY_PICK))
-
- def commit = commit()
- OKCommitDialogHandler handler = new OKCommitDialogHandler(myRepository)
- myVcsHelper.registerHandler(handler)
-
- invokeCherryPick(commit)
-
- assertNotCherryPicked()
- assertFalse "Commit dialog was shown, but it shouldn't", handler.wasCommitDialogShown()
- assertOnlyDefaultChangelist()
- assertNotificationShown("Cherry-pick failed",
- """
- ${commitDetails(commit)}
- Your local changes would be overwritten by cherry-pick.
- Commit your changes or stash them to proceed.
- """,
- NotificationType.ERROR)
- }
-
- @Test
- void "conflict, merge ok, commit cancelled, then new & active changelist"() {
- prepareConflict()
-
- CancelCommitDialogHandler handler = new CancelCommitDialogHandler()
- myVcsHelper.registerHandler(handler)
-
- GitCommit commit = commit()
- invokeCherryPick(commit)
- assertMergeDialogShown()
- assertTrue "Commit dialog was not shown", handler.wasCommitDialogShown()
- assertChangeLists([DEFAULT, newCommitMessage(commit)], newCommitMessage(commit))
- }
-
- @Test
- void "2 simple commits in a row, then 2 commit dialogs in a row"() {
- GitCommit commit1 = commit()
- GitCommit commit2 = commit()
-
- myGit.registerOperationExecutors(new MockGit.SimpleSuccessOperationExecutor(CHERRY_PICK, ""),
- new MockGit.SimpleSuccessOperationExecutor(CHERRY_PICK, ""))
-
- CountingOKCommitHandler handler = new CountingOKCommitHandler(myRepository)
- myVcsHelper.registerHandler(handler)
-
- invokeCherryPick([commit1, commit2])
-
- assertOnlyDefaultChangelist()
- assertEquals "Commit dialog shown wrong number of times", 2, handler.myCommitDialogs
- assertLastCommits(commit2, commit1)
- }
-
- @Test
- void "3 commits, 2nd conflicts with committed, then 1st success, on 2nd show merge dialog"() {
- GitCommit commit1 = commit("First")
- GitCommit commit2 = commit("Second")
- GitCommit commit3 = commit("Third")
-
- myGit.registerOperationExecutors(new MockGit.SimpleSuccessOperationExecutor(CHERRY_PICK, ""))
- prepareConflict()
- myGit.registerOperationExecutors(new MockGit.SimpleSuccessOperationExecutor(CHERRY_PICK, ""))
-
- CountingOKCommitHandler handler = new CountingOKCommitHandler(myRepository)
- myVcsHelper.registerHandler(handler)
-
- invokeCherryPick([commit1, commit2, commit3])
-
- assertMergeDialogShown()
- assertEquals "Commit dialog shown wrong number of times", 3, handler.myCommitDialogs
- assertLastCommits commit3, commit2, commit1
- }
-
- private static class CountingOKCommitHandler implements MockVcsHelper.CommitHandler {
-
- GitLightRepository myRepository
- int myCommitDialogs;
-
- CountingOKCommitHandler(GitLightRepository repository) {
- myRepository = repository
- }
-
- @Override
- boolean commit(String commitMessage) {
- myCommitDialogs++
- myRepository.commit(commitMessage)
- return true;
- }
-
- }
-
-}