push causes the error, the resolving pull creates the merge; the correct resolution has been pointed out as git pull --rebase but most people don't realize this.
Maybe somebody who has a habit of using --force when pushing. A major downside of rebase-centric workflows is that it teaches you to ignore the safety rails when pushing, or when deleting branches.
`--force-with-lease` would fix this problem (it needs an alias). Also, `--force` wouldn't cause a merge commit; it would overwrite the remote changes.
The only theory that makes sense is that this person doesn't know how to `pull --rebase`, but the order of `push` vs `pull` wouldn't change the presence of merge commits, so I'm still confused.
I don’t know git well, but I often run into the problem being discussed.
If I pull from origin before making my changes, I don’t have to merge, obviously.
But correct me if I’m wrong: I think that if I don’t pull first, but my changes don’t conflict with any part of what was done by the previous commit(s) I missed, I’ll still have to merge if I touched a file they touched.
This is a common scenario for me. Correct some typos in comments for example, and I get forced to figure out how to merge using vim, which I don’t know how to use at all (being a nano user). I’m sure I could and should switch to at least using nano by default, but I don’t know how merging really works, either.
What I really want to do is undo my commit, pull, and redo my commit. Then I don’t have to figure out git merge.
> I don’t know git well, but I often run into the problem being discussed.
I do understand the problem being discussed; what I don't understand is what it has to do with pushing first. You have the same problem no matter which order you use `git push` vs `git pull`.
> I think that if I don’t pull first, but my changes don’t conflict with any part of what was done by the previous commit(s) I missed, I’ll still have to merge if I touched a file they touched.
Yes, that's true.
> What I really want to do is undo my commit, pull, and redo my commit. Then I don’t have to figure out git merge.
You can do that with `git pull --rebase`, which, as others have mentioned, you can set as the default behavior of `git pull` like this:
Ooh, --force-with-lease looks like a nice feature, especially for updating github PRs that aren't yet merged. I still wouldn't want to use it where anybody else has a copy of the changes, since that's where you need a merge commit to avoid breaking somebody else's repo, but that gives me a safer option than a blind --force.
These may be specific to a workflow with git + github, when using git from the command line, but here are the cases I've run into where overriding safeties is needed.
1. After making a PR, there are conflicts when merging into main. In a merge-based workflow, I would merge main into the feature branch, resolve any conflicts, then push. In a rebase-based workflow, I rebase the branch onto main, resolve any conflicts, but now I need to push --force. As some of the other comments have mentioned, this can be improved with --force-with-lease, but still isn't the greatest.
2. After making a PR, there are some typos that need to be fixed. Fix these in an interactive rebase, to edit the same commit that introduced the typos. Also requires either --force or --force-with-lease.
3. When the PR is accepted, the result is rebased on top of main. My local branch still exists, and must be deleted. I would prefer to use `git branch -d` to delete the feature branch, but this rightfully says that the feature branch hasn't been merged in. I instead need to use `git branch -D` to forcefully delete it, introducing a point of human error. (There are some cases where git can delete the branch safely, which I think occurs either when the feature branch has only a single commit, or when the feature branch can be applied on top of main without a rebase, but I haven't exactly determined it.)
#1 and #3 are cases where a safer option cannot be used due to a rebase-workflow. #2 would exist in either case, since even in a merge workflow, rebasing of branches before they are pulled makes sense to do.
> There are some cases where git can delete the branch safely, which I think occurs either when the feature branch has only a single commit, or when the feature branch can be applied on top of main without a rebase, but I haven't exactly determined it.
FWIW: it occurs when the feature branch was based on the tip of master (because no-one else has committed to master since you branched/since you rebased onto master) - in this case rebasing your feature branch onto master is a no-op and the commits that go into master have the same hashes as they had on your feature branch.
I think I know git well, but you got me confused. I've never heard of pushes causing merges. Surely you are talking about pulls, right?