mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[git] write test on cherry-pick-without-auto-commit, remove old style cherry-pick tests
This commit is contained in:
@@ -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
|
||||
<hr/>
|
||||
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. <a href='view'>View them</a>
|
||||
"""
|
||||
|
||||
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
|
||||
@@ -141,8 +141,13 @@ public class GeneralStepdefs {
|
||||
git("commit -m 'adding files with initial content'");
|
||||
}
|
||||
|
||||
private static List<String> splitByComma(String listOfFiles) {
|
||||
return Arrays.asList(listOfFiles.split(", ?"));
|
||||
public static List<String> splitByComma(String listOfItems) {
|
||||
return Arrays.asList(listOfItems.split(", ?"));
|
||||
}
|
||||
|
||||
@Given("^branch (.+)$")
|
||||
public void branch(String branchName) throws Throwable {
|
||||
git("branch " + branchName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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<GitCommit> commits = new ArrayList<GitCommit>();
|
||||
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<Change> changes = new ArrayList<Change>();
|
||||
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<String> virtualHashes) {
|
||||
List<GitCommit> commits = new ArrayList<GitCommit>();
|
||||
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<Change> changes = new ArrayList<Change>();
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 <file>..." 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)}<br/>
|
||||
Your local changes would be overwritten by cherry-pick.<br/>
|
||||
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)}<br/>
|
||||
Some untracked working tree files would be overwritten by cherry-pick.<br/>
|
||||
Please move, remove or add them before you can cherry-pick. <a href='view'>View them</a>
|
||||
""",
|
||||
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)}<br/>
|
||||
Unresolved conflicts remain in the working tree. <a href='resolve'>Resolve them.<a/>
|
||||
""",
|
||||
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)}<br/>
|
||||
Your local changes would be overwritten by cherry-pick.<br/>
|
||||
Commit your changes or stash them to proceed.
|
||||
<hr/>
|
||||
However cherry-pick succeeded for the following commit:<br/>
|
||||
${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)}<br/>
|
||||
Not cherry-picked ${commitDetails(commit2)} - all changes have already been applied""", NotificationType.WARNING)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 <paths>' or 'git rm <paths>'
|
||||
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<Change> changes = new ArrayList<Change>();
|
||||
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<GitCommit> 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<String> changeLists, String activeChangelist) {
|
||||
ChangeListManager changeListManager = myPlatformFacade.getChangeListManager(myProject)
|
||||
List<LocalChangeList> lists = changeListManager.changeLists
|
||||
Collection<String> 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("<br/>")
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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)}
|
||||
<hr/>
|
||||
However cherry-pick succeeded for the following commit:<br/>
|
||||
${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)}<br/>
|
||||
Your local changes would be overwritten by cherry-pick.<br/>
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user