diff --git a/README.md b/README.md index d7223551..1b2814cb 100644 --- a/README.md +++ b/README.md @@ -157,6 +157,7 @@ using the matched rule and runs it. Rules enabled by default are as follows: * `fix_file` – opens a file with an error in your `$EDITOR`; * `git_add` – fixes *"pathspec 'foo' did not match any file(s) known to git."*; * `git_branch_delete` – changes `git branch -d` to `git branch -D`; +* `git_branch_exists` – offers `git branch -d foo`, `git branch -D foo` or `git checkout foo` when creating a branch that already exists; * `git_branch_list` – catches `git branch list` in place of `git branch` and removes created branch; * `git_checkout` – fixes branch name or creates new branch; * `git_diff_staged` – adds `--staged` to previous `git diff` with unexpected output; diff --git a/tests/rules/test_git_branch_exists.py b/tests/rules/test_git_branch_exists.py new file mode 100644 index 00000000..b41b0a41 --- /dev/null +++ b/tests/rules/test_git_branch_exists.py @@ -0,0 +1,33 @@ +import pytest +from thefuck.rules.git_branch_exists import match, get_new_command +from tests.utils import Command + + +@pytest.fixture +def stderr(branch_name): + return "fatal: A branch named '{}' already exists.".format(branch_name) + + +@pytest.fixture +def new_command(branch_name): + return [cmd.format(branch_name) for cmd in [ + 'git branch -d {0} && git branch {0}', + 'git branch -D {0} && git branch {0}', 'git checkout {0}']] + + +@pytest.mark.parametrize('script, branch_name', [ + ('git branch foo', 'foo'), + ('git branch bar', 'bar')]) +def test_match(stderr, script, branch_name): + assert match(Command(script=script, stderr=stderr)) + + +@pytest.mark.parametrize('script', ['git branch foo', 'git branch bar']) +def test_not_match(script): + assert not match(Command(script=script, stderr='')) + + +@pytest.mark.parametrize('script, branch_name, ', [ + ('git branch foo', 'foo'), ('git branch bar', 'bar')]) +def test_get_new_command(stderr, new_command, script, branch_name): + assert get_new_command(Command(script=script, stderr=stderr)) == new_command diff --git a/thefuck/rules/git_branch_exists.py b/thefuck/rules/git_branch_exists.py new file mode 100644 index 00000000..a2c00788 --- /dev/null +++ b/thefuck/rules/git_branch_exists.py @@ -0,0 +1,23 @@ +import re +from thefuck.shells import shell +from thefuck.specific.git import git_support +from thefuck.utils import eager + + +@git_support +def match(command): + return ('branch' in command.script + and "fatal: A branch named '" in command.stderr + and " already exists." in command.stderr) + + +@git_support +@eager +def get_new_command(command): + branch_name = re.findall( + r"fatal: A branch named '([^']*)' already exists.", command.stderr)[0] + new_command_templates = [['git branch -d {0}', 'git branch {0}'], + ['git branch -D {0}', 'git branch {0}'], + ['git checkout {0}']] + for new_command_template in new_command_templates: + yield shell.and_(*new_command_template).format(branch_name)