Please commit your changes or stash them before you merge что делать
Перейти к содержимому

Please commit your changes or stash them before you merge что делать

  • автор:

How to Fix Git Stash Merge Conflicts

Git stash allows you to save a draft of your in-progress changes and revert your working directory back to a clean slate. If stashed changes are applied ontop of new commits or other in-progress changes, there’s a chance for merge conflicts to arise.

If stash fails with a merge conflict, the error message will tell you that “git stash needs merge” or something similar to the messages below:

Note: This guide is a companion document to the video above. Merge conflicts are easier to understand when understood visually, so I recommend watching the video first.

How to fix a git stash needs merge error

Apply the stash

Note: If you have un-staged changes in your working directory, ensure you stage them by running git add . before running git stash pop . If unstaged files have merge conflicts, Git will abort the stash operation. You’ll know this happened if the message you receive contains the phrase “error: Your local changes to the following files would be overwritten by merge”. You’ll know you’ve entered the merge workflow when you see this phrase: “CONFLICT (content): Merge conflict”.

When stash fails with a merge conflict note the file(s) that failed the merge. Open each of the failed files in a text editor of your choice and manually resolve the conflicts. After saving the files, stage them:

At this point, you’ve resolved the conflicts and can continue development; however, you may want to consider commiting your changes before moving on for future readabily.

Lastly, when git stash pop fails with merge conflicts, the stash entry isn’t removed from the stash list. After fixing the merge conflict, remove the stash entry by running:

Workarounds

If you’d rather not fix a merge conflict right away, you can pop you changes out onto a new branch instead of the branch on which the stash was created:

This will allow you to continue development on a separate branch, then use merge/rebase to bring those branched changes back onto mainline at your leasure.

“brew update” fails with a merge error

Remy Porter

It had been awhile since I had last updated my homebrew install, so I popped into the command line to run the trusty “brew update” command, but instead, I was greeted with this:

$ brew update
error: Your local changes to the following files would be overwritten by merge: README.md

Please, commit your changes or stash them before you can merge.
Aborting Error: Failure while executing: git pull -q origin refs/heads/master:refs/remotes/origin/master

Well, crap, I have no idea what README.md file it’s talking about, or even the start of a hint of how to find it. Do I have to do some sort of search through my whole filesystem to find it? Can I narrow it down to my Cellar?

Or am I just an idiot? brew —prefix tells me the root directory for my homebrew install, and that’s also where the git repo for it lives. I solved the problem by doing the following:

$ cd `brew —prefix` #go to the git repo
$ git checkout — . #destroy all unstaged changes

Ошибки git «Your local changes to the following files would be overwritten by merge» и «Please commit your changes or stash them before you merge» (РЕШЕНО)

Чтобы синхронизировать (обновить) свой локальный репозиторий с удалённым, используется команда:

Но она может закончиться неудачей и вызвать следующую ошибку:

Суть ошибки в том, что на удалённом репозитории сделаны изменения, но они не могут быть приняты, поскольку в вашем локальном репозитории тоже сделаны изменения и в результате если будут приняты обновления, то ваши локальные данные потеряются.

Такое может произойти по разным причинам, например, вы чуть подправили файл, или вы подготовили изменения для отправки на удалённый репозиторий и отправили их (сделали commit), но эти изменения ещё не приняты. В любом из этих случаев вы столкнётесь с этой ошибкой.

В ошибке показан проблемный файл (в данном случае это data/cf-subnet.txt), для проверки, были изменения на удалённом репозитории или в вашем локальном репозитории, вы также можете использовать команду:

Она также покажет список не синхронизированных файлов.

Подсказка в ошибке предлагает сделать commit или stash.

Но вариантов исправить эту ошибку четыре.

1. Отправить изменения (сделать commit)

2. Сделать stash

Если вы не знаете, что такое stash, то stash это как стек, временное хранилище, куда вы можете отправить сделанные изменения, а затем вернуть их обратно.

Чтобы спрятать изменения, то есть сделать stash выполните:

Затем примите изменения из удалённого репозитория (git pull).

А затем верните свои изменения из stash:

Ну а если стек спрятанных изменений вам вовсе не нужен, то его удалить можно следующей командой:

3. Отменить локальные изменения

Чтобы сбросить изменения в локальном репозитории выполните команду:

4. Сбросить локальные изменения для определённого файла

Чтобы сделать это, используйте команду вида:

Заключение

Какой бы способ вы не выбрали, после любого из этих вариантов вы можете обновить свой локальный репозиторий до последней версии с помощью:

29 Pull, but you have local work

Problem: You want to pull changes from upstream, but you have done some new work locally since the last time you pulled. This often comes up because what you actually want to do is push, but Git won’t let you until you first incorporate the upstream changes.

For the sake of simplicity, assume we’re dealing with the main branch and the remote is called origin .

Recent commit history of origin/main :

Recent commit history of the local main branch:

Your goal: get commit C into your local branch, while retaining the work in commit D or your uncommitted changes.

  • Local state is A—B—(uncommitted changes) : You could use git stash . Or you could just make a commit to simplify your life (see next bullet).
  • Local state is A—B—D : You can get to A—B—C—D or A—B—(something that includes C and D) .
  • Local state is A—B—D—(uncommitted changes) : You could just make a commit – a new one or amend D – to simplify your life (see previous bullet).

We prioritize simple approaches that are good for early Git use, but mention nicer long-term alternatives.

29.1 Local work is uncommitted

Remote state is A—B—C .
Local state is A—B—(uncommitted changes) .

29.1.1 Happy simple cases

There are two happy scenarios, in which git pull will “just work”:

  • You’ve introduced completely new files that don’t exist in the remote branch and, therefore, cannot possibly have conflicting changes. You’re in luck! You can just git pull .
  • The files affected by your local work have ZERO overlap with the files affected by the changes you need to pull from the remote. You’re also in luck! You can just git pull .

Summary of these happy git pull scenarios:

What has actually happened here is that git pull resulted in a fast-forward merge, i.e. we placed commit C right on the end of your history. This would also be the case in the simpler situation where recent local history was just A—B , i.e. you had not added any local work since the last sync up with origin/main .

29.1.2 git stash works, sometimes

If your changes affect a file ( foo.R in the example below) that has also been changed in commit C , you cannot git pull . It doesn’t hurt to try, but you will fail and it will look something like this:

Now what? First, you must safeguard your local changes by either stashing or committing them. (I personally would choose to commit and execute a workflow described in 29.2.)

I am not a big fan of git stash ; I think it’s usually better to take every possible chance to solidify your skills around core concepts and operations, e.g., make a commit, possibly in a branch. But if you want to use git stash , this opportunity is as good as it gets.

git stash is a way to temporarily store some changes to get them out of the way. Now you can do something else, without a lot of fuss. In our case, “do something else” is to get the upstream changes with a nice, simple git pull . Then you reapply and delete the stash and pick up where you left off.

For more details about stashing, I recommend

  • The stashing coverage in the “Filesystem interactions” chapter of Git in Practice (book website or read on GitHub)
  • 7.3 Git Tools — Stashing and Cleaning in Pro Git.

Here’s the best case scenario for “stash, pull, unstash” in the example above:

And here’s the output from our example:

That is what success looks like. You’ve achieved this:

As above, we have just enjoyed a fast-forward merge, made possible by temporarily stashing then unstashing the uncommitted local changes.

29.1.3 git stash with conflicts

If your local changes have some overlap with changes you are pulling, you will, instead get a merge conflict from git stash pop . Now you have some remedial work to do. In this case, you have gained nothing by using git stash in the first place, which explains my general lack of enthusiasm for git stash .

Here’s how to execute the git stash workflow in our example, in the face of conflicts (based on this Stack Overflow answer):

At this point, you must resolve the merge conflict (future link). Literally, at each locus of conflict, pick one version or the other (upstream or stashed) or create a hybrid yourself. Remove the all the markers inserted to demarcate the conflicts. Save.

Since git stash pop did not go smoothly, we need to manually reset (future link) and delete the stash to finish.

Phew, we are done. We’ve achieved this:

The asterisk on uncommitted changes* indicates that your uncommitted changes might now reflect adjustments made when you resolved the conflicts.

29.2 Local work is committed

Remote state is A—B—C .
Local state is A—B—D .

29.2.1 Pull (fetch and merge)

The simplest option is to fetch the commits from upstream and merge them, which is what git pull does. This is a good option if you’re new to Git. It leads to a messier history, but when you are new, this is the least of your worries. Merge, be happy, and carry on.

Here is the best case, no-merge-conflicts version of git pull :

Depending on your version of Git, your config, and your use of a GUI, you might be required to confirm/edit a commit message for the merge commit.

Or what if things don’t go this smoothly? If commit C (on the remote) and commit D (local) have changes to the same parts of one or more files, Git may not be able to automatically merge and you will get merge conflicts. It will look something like this:

You must resolve these conflicts (future link). Literally, at each locus of conflict, pick one version or the other (upstream or local) or create a hybrid yourself. Remove the all the markers inserted to demarcate the conflicts. Save.

Mark the affected file foo.R as resolved via git add and make an explicit git commit to finalize this merge.

Again, do not be surprised if, during git commit , you find yourself in an editor, confirming/editing the commit message for the merge commit.

We’ve achieved this:

29.2.2 Pull and rebase

git pull —rebase creates a nicer history than git pull when integrating local and remote commits. It avoids a merge commit, so the history is less cluttered and is linear. It can make merge conflicts more onerous to resolve, which is why I still recommend git pull as the entry-level solution.

Here is the best case, no-merge-conflicts version of git pull —rebase :

Notice that you were NOT kicked into an editor to fiddle with the commit message for the merge commit, because there is no merge commit! This is the beauty of rebasing.

We’ve achieved this:

It is as if we pulled the upstream work in commit C , then did the local work embodied in commit D . We have no cluttery merge commits and a linear history. Nice!

The bad news: As with plain vanilla git pull , it is still possible to get merge conflicts with git pull —rebase . If you have multiple local commits, you can even find yourself resolving conflicts over and over, as these commits are sequentially replayed. Hence this is a better fit for more experienced Git users and in situations where conflicts are unlikely (those tend to be correlated, actually).

At this point, if you try to do git pull —rebase and get bogged down in merge conflicts, I recommend git rebase —abort to back out. For now, just pursue a more straightforward strategy.

29.3 Other approaches

There are many more ways to handle this situation, which you can discover and explore as you gain experience and start to care more about the history. We sketch some ideas here.

29.3.1 Use a temporary branch for local work

Recall:
Remote state is A—B—C .
Local state is A—B—(uncommitted changes) .

This is an alternative to the stash workflow that has the advantage of giving you practice with Git techniques that are more generally useful. It also leads to a nice history.

Create a new, temporary branch and commit your uncommitted changes there. Checkout main and git pull to get changes from upstream. You now need to recover the work from the commit in the temporary branch. Options:

  • Merge the temporary branch into main .
  • Cherry pick the commit from the temporary branch into main .

In either case, it is still possible you will need to deal with merge conflicts.

In either case, if you felt forced to commit before you were ready or to accept an ugly merge commit, you can either do a mixed reset to “uncommit” but keep the changes on main or keep amending until you are satisfied with the commit.

29.4 Some local work is committed, some is not

This is an awkward hybrid situation that can be handled with a combination of strategies seen above: make a pragmatic commit on main or a temporary branch. Integrate the upstream and local changes in main . If you aren’t happy with the final pragmatic commit (which only exists locally), reset or amend until you are.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *