I have a local fork with big changes that I can't maintain and I want to synchronize it with a remote upstream branch. When I merge upstream into my fork, I would like the commits that conflict with my fork to be simply ignored. Do you know how to do this?
To summarize, I would like to:
- ignore any commits that conflict.
- Never overwrite local files.
- Have an up-to-date fork.
Thanks!
CodePudding user response:
Keeping your fork up-to-dated to the upstream means, you basically need to connect your branch there by git-merge
. But as you know, even if you want to discard certain commits, the history will be on your merged commit so you need some handling to "discard" such commits. I would suggest a revert before running the merge.
So, if you can manually spend effort to selectively pick commits to discard, you can locally revert them before running merge.
git checkout upstream/master
git revert bad-commit-yesterday # NOTE: the order of revert matters
git revert bad-commit-one-month-ago # commit-hash = e.g., abcde123
git checkout origin/master
git merge --log abcde123
Alternatively, if you want to do this very quick, here's the dirty method.
git checkout origin/master # your repo
git merge --log upstream/master # Conflict
git checkout origin/master - <file_path_1> ... # I assume you want to keep your "local" change in origin/master
CodePudding user response:
Git's git merge
does not work commit-by-commit. To skip commits that cause conflicts would require that you work commit-by-commit. You would need to write your own software to do this. That part would be relatively easy in all linear cases, but would rapidly bog down in complex cases (merging commit sequences that contain merges), and would have little value in most practical systems because skipping a commit that causes an earlier merge conflict will often result in most or all subsequent commits having a merge conflict.
In other words, given a commit stream like this:
... <-F <-G <-H <-I ...
as you attempt to "cherry-merge"1 commits one at a time, if you skip G
because it has a conflict, you will find that H
depends on G
and therefore has a conflict, and I
depends on H
and therefore has a conflict, and so on.
The final result of this is that you merge up to some stasis point, and then stop acquiring most new commits. So I would recommend not even attempting this. You may have an oddball case where this doesn't really happen, though, and in that case, feel free to take a stab at writing "cherry-merge".
1This is my made-up name for the new Git command you need to write. It's a combination of cherry-pick and merge, so I named it "cherry-merge", but that may be a terrible name in the end. Naming is one of the hard problems in computing, after all.
(I'm somewhat mis-using the "naming things" idea here, on purpose, but it applies. I'm also alluding to the joke variants that add "off by one" errors to the "two hard things".)