From 8c62706db40008e63b85e43dd1b41c3c1798acae Mon Sep 17 00:00:00 2001 From: Joseph Frazier <1212jtraceur@gmail.com> Date: Sun, 11 Dec 2016 12:37:09 -0500 Subject: [PATCH] Fix `git stash pop` with local changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When there are local changes to a file, and a git stash is popped that contains other changes to that same file, git fails as follows: $ git stash pop error: Your local changes to the following files would be overwritten by merge: src/index.js Please commit your changes or stash them before you merge. Aborting $ This change adds a rule that corrects this problem as suggested [here]: $ git stash pop error: Your local changes to the following files would be overwritten by merge: src/index.js Please commit your changes or stash them before you merge. Aborting $ fuck git add . && git stash pop && git reset . [enter/↑/↓/ctrl+c] Auto-merging src/index.js On branch flow Changes to be committed: (use "git reset HEAD ..." to unstage) modified: src/index.js Changes not staged for commit: (use "git add ..." to update what will be committed) (use "git checkout -- ..." to discard changes in working directory) modified: src/index.js Dropped refs/stash@{0} (f94776d484c4278997ac6837a7b138b9b9cdead1) Unstaged changes after reset: M src/index.js $ [here]: https://stackoverflow.com/questions/15126463/how-do-i-merge-local-modifications-with-a-git-stash-without-an-extra-commit/15126489#15126489 --- README.md | 1 + tests/rules/test_git_stash_pop.py | 18 ++++++++++++++++++ thefuck/rules/git_stash_pop.py | 18 ++++++++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 tests/rules/test_git_stash_pop.py create mode 100644 thefuck/rules/git_stash_pop.py diff --git a/README.md b/README.md index 9c149bc1..e0c42e94 100644 --- a/README.md +++ b/README.md @@ -187,6 +187,7 @@ using the matched rule and runs it. Rules enabled by default are as follows: * `git_rebase_merge_dir` – offers `git rebase (--continue | --abort | --skip)` or removing the `.git/rebase-merge` dir when a rebase is in progress; * `git_remote_seturl_add` – runs `git remote add` when `git remote set_url` on nonexistant remote; * `git_stash` – stashes you local modifications before rebasing or switching branch; +* `git_stash_pop` – adds your local modifications before popping stash, then resets; * `git_two_dashes` – adds a missing dash to commands like `git commit -amend` or `git rebase -continue`; * `go_run` – appends `.go` extension when compiling/running Go programs; * `gradle_no_task` – fixes not found or ambiguous `gradle` task; diff --git a/tests/rules/test_git_stash_pop.py b/tests/rules/test_git_stash_pop.py new file mode 100644 index 00000000..1ff34686 --- /dev/null +++ b/tests/rules/test_git_stash_pop.py @@ -0,0 +1,18 @@ +import pytest +from thefuck.rules.git_stash_pop import match, get_new_command +from tests.utils import Command + + +@pytest.fixture +def stderr(): + return '''error: Your local changes to the following files would be overwritten by merge:''' + + +def test_match(stderr): + assert match(Command('git stash pop', stderr=stderr)) + assert not match(Command('git stash')) + + +def test_get_new_command(stderr): + assert get_new_command(Command('git stash pop', stderr=stderr)) \ + == "git add . && git stash pop && git reset ." diff --git a/thefuck/rules/git_stash_pop.py b/thefuck/rules/git_stash_pop.py new file mode 100644 index 00000000..2073c234 --- /dev/null +++ b/thefuck/rules/git_stash_pop.py @@ -0,0 +1,18 @@ +from thefuck.shells import shell +from thefuck.specific.git import git_support + + +@git_support +def match(command): + return ('stash' in command.script + and 'pop' in command.script + and 'Your local changes to the following files would be overwritten by merge' in command.stderr) + + +@git_support +def get_new_command(command): + return shell.and_('git add .', 'git stash pop', 'git reset .') + + +# make it come before the other applicable rules +priority = 900