質問

I have what I think is a really strange problem with merge conflicts during a rebase.

I'm trying to rebase a feature branch with a development branch:

git checkout myFeatureBranch
git rebase developBranch

Now git rebase reports conflicts and I have to use git mergetool to resolve conflicts.

git mergetool

Git mergetool declares a conflicted file myFile1.h and the merge interface opens (the problem occurs on either Linux or Windows/tortoisegit for the same repo). What I see is that the "theirs" file is completely the wrong file myOtherFile.c although the "mine" file is correctly showing myFile1.h.

I've tried git gc --aggressive and git fsck --full. git gc reports no problems at all and git fsck has a lot of dangling stuff but no errors or missing information.

Is this some kind of corruption in the git database and if so, can it be repaired?

Any other possibilities for what is wrong?

I did think that perhaps I could merge the "mine" file back onto itself (ignoring all the incorrect "theirs" changes completely), and maybe this would clean up the problem, but I fear it could also make things worse.

Whatever the problem is, it does appear to be in our master remote repo as new clones exhibit the same rebase problem.

Thanks for your help.

git config -l output with some redaction:

core.symlinks=false
core.autocrlf=input
color.diff=auto
color.status=auto
color.branch=auto
color.interactive=true
pack.packsizelimit=2g
help.format=html
http.sslcainfo=/bin/curl-ca-bundle.crt
sendemail.smtpserver=/bin/msmtp.exe
diff.astextplain.textconv=astextplain
rebase.autosquash=true
core.autocrlf=true
core.excludesfile=<global exclude file>
user.name=Russell
user.email=<email address>
push.default=simple
core.repositoryformatversion=0
core.filemode=false
core.bare=false
core.logallrefupdates=true
core.symlinks=false
core.ignorecase=true
core.hidedotfiles=dotGitOnly
remote.origin.url=<gituser@gitserver>
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
remote.origin.puttykeyfile=<key.ppk>
branch.master.remote=origin
branch.master.merge=refs/heads/master
branch.develop.remote=origin
branch.develop.merge=refs/heads/develop
branch.myFeatureBranch.remote=origin
branch.myFeatureBranch.merge=refs/heads/myFeatureBranch
役に立ちましたか?

解決 2

git rebase -p develop seemed to do the trick. Thanks to jthill.

I haven't yet tried torek's answer, but I plan to explore that as well, out of curiosity.

他のヒント

You're running into git's rename detection.

First, some important notes about rebase.

  1. Rebase uses the merge machinery.

  2. In a merge (e.g., merging feature into master) you would say "the branch I am on, master, is ‘our’ code and the branch I am merging-in, feature, is ‘their’ code".

When you rebase code, the "ours" side is the code you are rebasing to, and the "theirs" code is the code you are rebasing—i.e., your own code. In effect, the "sides" are swapped. (See the -m, -s, and -X arguments to git rebase and the note about sides being swapped.)

Inside the merge machinery, using the default (recursive) strategy, git thinks "our" myFile1.h (i.e., the one from develop) is more similar to "their" myOtherFile.c (i.e., your own version of that file) than to "their" (i.e., your) myFile1.h. So it's trying to merge the wrong files.

Moving over to the git merge documentation, note the options you can pass to recursive. The most important one is probably rename-threshold=<n>. So, you can pass -X rename-threshold=100 (or any number sufficiently higher than 50). I have never actually run into this issue myself but that seems like it should do the trick.

Why would merges in the history make any difference?

Rebase is a noise-reduction tool to keep timewasting redundancies out of pu{bli,}shed history. Once you've done what deserves to be written, rebase is the "write what deserves to be read" helper. For a blow-by-blow you'd just merge, when that would unnecessarily complicate readers' jobs a linear[ized] one-for-one is almost always good enough and easy, so that's what rebase tries for by default. If it turns out not so easy, there's -i and -p, --interactive and --preserve-merges, to help with the more intricate editing.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top