2

I read the following post: How do you git fetch then merge? "Error: Your local changes to the following files would be overwritten by merge"

I work with my friend on the same branch with git. When he did changes to our project and he pulls the project, he gets the error, that his local changes will be overwritten.

Is this a possible workflow in order to push his new changes:

git commit 
git pull (or fetch and merge)
git push

Or is git stash better than git commit

Mureinik
  • 297,002
  • 52
  • 306
  • 350
David
  • 2,926
  • 1
  • 27
  • 61

3 Answers3

2

You should usually only commit if you have a complete changeset (which usually means it compiles without warnings, all tests pass, and it achieves some logical improvement).

If you have such a "complete" change, by all means, you should commit it. If not, it's probably better to stash your changes, pull from the remote, and pop the stashed changes back to your working index.

Mureinik
  • 297,002
  • 52
  • 306
  • 350
  • Could it be possible then, that I will not commit for days and does that not endanger the project, if my data on my computer gets lost? – David Mar 29 '19 at 19:01
  • 1
    That's a valid concern. This is why some people make several commits and then squash them. Personally, I think it's better practice to try to make your "complete changes" small enough that you can finish them in a day. In the end, it's a personal decision what level of risk you're OK with (how much uncommitted code) and how you want to manage your commits and branches. – mkasberg Apr 02 '19 at 14:22
1

This is fine (and the work will be committed):

git commit 
git pull (or fetch and merge)
git push

This is also fine (and the work will not be committed):

git stash save
git pull (or fetch and merge)
git stash pop
mkasberg
  • 16,022
  • 3
  • 42
  • 46
  • You can even omit the `save`, therefore `git stash` results: `Saved working directory and index state WIP on master: 570f85b commit from ..`. – Timo May 08 '21 at 12:30
1

In the following, I don't mention use of pull; as you note, it is basically fetch followed by merge (unless configured to be something different), so you can substitute it as appropriate.

Probably the simplest workflow for two people sharing a branch is commit, fetch, merge, push. It's probably fine to treat that as the default, recognizing the reasons why you would do something different:

First, this does assume you've reached a state locally where you would want to create a permanent commit point. What criteria you have for that would be a discussion for your team, but basically you're just saying it's a point you should be able to return to in the future. You probably don't want to clutter your history with a bunch of partially-completed changes, and for debugging purposes some teams say that every permanent commit should pass automated tests.

This is important because if you're at a commit O, you have local changes which you commit as L, and then fetch and merge remote commit R, you end up with something like

O -- L -- M <--(master)
 \       /
  -- R --

Now L is basically locked into your history (especially after a subsequent push). So for example, if you then make some more local changes and commit them giving

O -- L -- M -- L2 <--(master)
 \       /
  -- R --

there is not a straightforward way to squash L and L2 together.

The simplest way to address this is to stash your local changes instead of committing them if they are not ready to be committed. When you pop (or apply) the stash, you'd still have to resolve any conflicts. The result would be

O -- R <--(master)

with uncommitted (and possibly unstaged, depending on how you handle the stash) changes.

Another common variation is to rebase local changes on top of the newly-fetched commits. This can make the history look simpler (doing away with commits to merge local changes with remote ones), and since it keeps your local changes at the tip it makes it easier to amend them (as long as you haven't pushed them). But, it also creates commit states that haven't really passed whatever automated tests you might have, so could run afoul if you want a 'clean commit' policy as suggested above.

Mark Adelsberger
  • 42,148
  • 4
  • 35
  • 52