First you need to make your observations a bit more consistent. You start by giving the timeline
At time0 someone else changed file B and push to remote.
At time1 I change file A in my machine, and committed
(emphasis added). Then you compare your situation to a question titled " git pull creates merge commit even when i have no local changes" (emphasis added).
Of course that answer isn't applicable to you; you have local changes.
And when you have local changes, the normal behavior is to create a merge commit when pulling remote changes.
Then you said that the git-tower client didn't produce a merge commit. There are three reasons that could happen.
1) The client could be configured to rebase instead of merge; but you've said that's not the case.
2) There could be no local changes
3) There could be no remote changes - which, if you were trying this right after observing a pull that created a merge, is pretty likely, since the changes in the merge are no longer just remote.
So the question isn't what's wrong with your git setup; the question is what options you have if you don't want the merge commits.
An option I missed, which torek points out in comments below, is to use the more fundamental commands. So fetch
the changes, and then integrate them into your local in whatever way you want (by merge
or rebase
, etc.). Until you're really comfortable with what the commands do, that might be the best option.
(I know git specifically says to pull in its error message; but a pull and (merge or fetch) will do just as well.)
Another option is to use rebase. This is considered potentially dangerous according to the git docs, but it is a reasonably common practice. If you understand rebase and its implications, it's a reasonable way to go. To configure git to use rebase you could do something like
git config --global pull.rebase true
Another option is to use different branches locally than exist on the remote. (This may sound odd, but there are viable workflows based on this idea.) In that case, your merges or rebases are explicitly chosen when you integrate one branch to another, rather than being forced when you implicitly integrate changes through a pull.