From 569709388dd269e1ad7af4a53086dbdf09afd3f7 Mon Sep 17 00:00:00 2001 From: mcarton Date: Mon, 20 Jul 2015 18:20:29 +0200 Subject: [PATCH 1/3] Add a `git_push_force` rule --- tests/rules/test_git_push_force.py | 52 ++++++++++++++++++++++++++++++ thefuck/rules/git_push_force.py | 15 +++++++++ 2 files changed, 67 insertions(+) create mode 100644 tests/rules/test_git_push_force.py create mode 100644 thefuck/rules/git_push_force.py diff --git a/tests/rules/test_git_push_force.py b/tests/rules/test_git_push_force.py new file mode 100644 index 0000000..c55e77d --- /dev/null +++ b/tests/rules/test_git_push_force.py @@ -0,0 +1,52 @@ +import pytest +from thefuck.rules.git_push_force import match, get_new_command +from tests.utils import Command + + +git_err = ''' +To /tmp/foo + ! [rejected] master -> master (non-fast-forward) + error: failed to push some refs to '/tmp/bar' + hint: Updates were rejected because the tip of your current branch is behind + hint: its remote counterpart. Integrate the remote changes (e.g. + hint: 'git pull ...') before pushing again. + hint: See the 'Note about fast-forwards' in 'git push --help' for details. +''' + +git_uptodate = 'Everything up-to-date' +git_ok = ''' +Counting objects: 3, done. +Delta compression using up to 4 threads. +Compressing objects: 100% (2/2), done. +Writing objects: 100% (3/3), 282 bytes | 0 bytes/s, done. +Total 3 (delta 0), reused 0 (delta 0) +To /tmp/bar + 514eed3..f269c79 master -> master +''' + + +@pytest.mark.parametrize('command', [ + Command(script='git push', stderr=git_err), + Command(script='git push nvbn', stderr=git_err), + Command(script='git push nvbn master', stderr=git_err)]) +def test_match(command): + assert match(command, None) + + +@pytest.mark.parametrize('command', [ + Command(script='git push', stderr=git_ok), + Command(script='git push', stderr=git_uptodate), + Command(script='git push nvbn', stderr=git_ok), + Command(script='git push nvbn master', stderr=git_uptodate), + Command(script='git push nvbn', stderr=git_ok), + Command(script='git push nvbn master', stderr=git_uptodate)]) +def test_not_match(command): + assert not match(command, None) + + +@pytest.mark.parametrize('command, output', [ + (Command(script='git push', stderr=git_err), 'git push --force'), + (Command(script='git push nvbn', stderr=git_err), 'git push --force nvbn'), + (Command(script='git push nvbn master', stderr=git_err), 'git push --force nvbn master')]) +def test_get_new_command(command, output): + assert get_new_command(command, None) == output diff --git a/thefuck/rules/git_push_force.py b/thefuck/rules/git_push_force.py new file mode 100644 index 0000000..53d2117 --- /dev/null +++ b/thefuck/rules/git_push_force.py @@ -0,0 +1,15 @@ +from thefuck import utils + + +@utils.git_support +def match(command, settings): + return ('git' in command.script + and 'push' in command.script + and '! [rejected]' in command.stderr + and 'failed to push some refs to' in command.stderr + and 'Updates were rejected because the tip of your current branch is behind' in command.stderr) + + +@utils.git_support +def get_new_command(command, settings): + return command.script.replace('push', 'push --force') From bb7579ead5c53a8fb69d6c5e8a505ee4eafdd160 Mon Sep 17 00:00:00 2001 From: mcarton Date: Mon, 20 Jul 2015 18:42:05 +0200 Subject: [PATCH 2/3] Add the `git_pull_clone` rule --- tests/rules/test_git_pull_clone.py | 21 +++++++++++++++++++++ thefuck/rules/git_pull_clone.py | 14 ++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 tests/rules/test_git_pull_clone.py create mode 100644 thefuck/rules/git_pull_clone.py diff --git a/tests/rules/test_git_pull_clone.py b/tests/rules/test_git_pull_clone.py new file mode 100644 index 0000000..07249fa --- /dev/null +++ b/tests/rules/test_git_pull_clone.py @@ -0,0 +1,21 @@ +import pytest +from thefuck.rules.git_pull_clone import match, get_new_command +from tests.utils import Command + + +git_err = ''' +fatal: Not a git repository (or any parent up to mount point /home) +Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set). +''' + + +@pytest.mark.parametrize('command', [ + Command(script='git pull git@github.com:mcarton/thefuck.git', stderr=git_err)]) +def test_match(command): + assert match(command, None) + + +@pytest.mark.parametrize('command, output', [ + (Command(script='git pull git@github.com:mcarton/thefuck.git', stderr=git_err), 'git clone git@github.com:mcarton/thefuck.git')]) +def test_get_new_command(command, output): + assert get_new_command(command, None) == output diff --git a/thefuck/rules/git_pull_clone.py b/thefuck/rules/git_pull_clone.py new file mode 100644 index 0000000..c5e68a7 --- /dev/null +++ b/thefuck/rules/git_pull_clone.py @@ -0,0 +1,14 @@ +import re +from thefuck import utils, shells + + +@utils.git_support +def match(command, settings): + return ('git pull' in command.script + and 'fatal: Not a git repository' in command.stderr + and "Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set)." in command.stderr) + + +@utils.git_support +def get_new_command(command, settings): + return command.script.replace(' pull ', ' clone ') From 0f67aad93b82d447871712700a1b8b1f83fc79ad Mon Sep 17 00:00:00 2001 From: mcarton Date: Mon, 20 Jul 2015 18:47:59 +0200 Subject: [PATCH 3/3] Update README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 950214e..1a8d80d 100644 --- a/README.md +++ b/README.md @@ -167,7 +167,9 @@ using the matched rule and runs it. Rules enabled by default are as follows: * `git_diff_staged` – adds `--staged` to previous `git diff` with unexpected output; * `git_no_command` – fixes wrong git commands like `git brnch`; * `git_pull` – sets upstream before executing previous `git pull`; +* `git_pull_clone` – clones instead of pulling when the repo does not exist; * `git_push` – adds `--set-upstream origin $branch` to previous failed `git push`; +* `git_push_force` – adds `--force` to a `git push`; * `git_stash` – stashes you local modifications before rebasing or switching branch; * `go_run` – appends `.go` extension when compiling/running Go programs * `grep_recursive` – adds `-r` when you trying to grep directory;