I want to enforce (i.e. throw an error and fail) that whenever I do a git merge I don’t have any unstaged changes, much in the same why a git rebase will not work if unstaged changes exist. Is there a way to do this?
Share
Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.
Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.
Lost your password? Please enter your email address. You will receive a link and will create a new password via email.
Please briefly explain why you feel this question should be reported.
Please briefly explain why you feel this answer should be reported.
Please briefly explain why you feel this user should be reported.
It ain’t pretty, but it works. I’d be interested in seeing a better solution.
Git already rejects the merge if the file to be merged is dirty:
$ git init Initialized empty Git repository in /tmp/mmm/.git/ $ echo this is file1 > file1 $ git add file1 $ git ci -m'first commit' file1 [master (root-commit) efd89a6] first commit 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 file1 $ git co -b branch1 Switched to a new branch 'branch1' $ echo change file1 >> file1 $ git ci -m'change on a branch' file1 [branch1 031e317] change on a branch 1 files changed, 1 insertions(+), 0 deletions(-) $ git co master Switched to branch 'master' $ echo change on master >> file1 $ git merge branch1 Updating efd89a6..031e317 error: Your local changes to 'file1' would be overwritten by merge. Aborting. Please, commit your changes or stash them before you can merge.Continuing the example:
$ git ci -m'commit change on master' file1 [master 8a2d52c] commit change on master 1 files changed, 1 insertions(+), 0 deletions(-) $ git merge branch1 Auto-merging file1 CONFLICT (content): Merge conflict in file1 Automatic merge failed; fix conflicts and then commit the result. $ vi file1 $ git add file1 $ git ci [master ee16606] Merge branch 'branch1' $ git log --oneline ee16606 Merge branch 'branch1' 8a2d52c commit change on master 031e317 change on a branch efd89a6 first commit $ echo this is file2 > file2 $ git add file2 $ git co -b branch2 A file2 Switched to a new branch 'branch2' $ echo change on branch2 >> file2 $ git ci -m'commit on branch2' file2 [branch2 06ff9c3] commit on branch2 1 files changed, 2 insertions(+), 0 deletions(-) create mode 100644 file2 $ git co master Switched to branch 'master' $ echo this change logically conflicts with the change to file2 on branch2 >> file1It is the next command that you want to force a failure — you want to avoid this merge when your tree is dirty. You can do this in the prepare-commit-msg hook, but only if you do –no-ff merges, and don’t let the merge automatically commit. Here’s an outline of the hook:
You have to use –no-ff and –no-commit, on every branch that you’d be merging into and want to protect from merges like this:
git config branch.master.mergeoptions "--no-commit --no-ff"And here’s what the session would look like:
$ git merge branch2 Automatic merge went well; stopped before committing as requested $ git ci IN THE PREP HOOK: .git/COMMIT_EDITMSG, merge, Check here if the working tree is dirty. If it is, fail. $ git status # On branch master # Changes to be committed: # # modified: file2 # # Changed but not updated: # (use "git add ..." to update what will be committed) # (use "git checkout -- ..." to discard changes in working directory) # # modified: file1 # bstpierre@bstpierre 1119 /tmp/mmm master $ git ci IN THE PREP HOOK: .git/COMMIT_EDITMSG, merge, Check here if the working tree is dirty. If it is, fail. bstpierre@bstpierre 1120 /tmp/mmm master $ echo $? 1And undoing back to the pre-merge state:
$ git reset --merge $ git status # On branch master # Changed but not updated: # (use "git add ..." to update what will be committed) # (use "git checkout -- ..." to discard changes in working directory) # # modified: file1 # no changes added to commit (use "git add" and/or "git commit -a")