Git rebase continually fails and requires manual merge intervention

I am having an issue with rebasing from master on to a 'deploy' branch within one of my repositories.

My repo is setup as follows:

master - of course, the main branch
deploy - a branch created where files like Capfile, deploy.rb etc are created and configured - these changes will NEVER be merged back into Master

Generally my workflow is:

  • Do development on the master branch... test, smile, commit.
  • Checkout the deploy branch
  • Execute git rebase master on the deploy branch - this used to work without a problem
  • Push to remote and then execute cap deploy
  • Relax
  • The problem I am now having is that when I execute git rebase master on the deploy branch it is coming up with a 3-way merge/manual merge required error (I don't think the error message is really generic enough to post). Git tells me to perform a merge then use git rebase --continue to finish - which never works.

    What I have found 'does' work is running git rebase master --interactive , cleaning up the pick list (there is 5 or so repeated 'commits' but with different reference numbers (same message) in this list, so I'll choose one of them) and then manually do the merge. Once I have done this for each commit then I can continue the rebase and its all happy...

    Until next time I need to perform a rebase.

    So does anyone know what might be happy? The project isn't really 'secret' so if need be I can post messages, logs, branch graphs etc.

    Thanks


    What sounds like it might be happening is that you have changed the commit history of those "repeated" commits such that they have a different sha1. Each sha1 is unique to not only the commit, but the commit history. Hence, it's impossible (well, highly improbably to happen during the lifetime of the universe), to have two identicial sha1 in the same history or to have two sha1 in two different histories even. If you change anything in your commit, such as with an amend or interactive rebase, then you will change the sha1. So two commits that might look the same, are actually treated differently.

    So very likely, you rebased from the other branch, did some type of interactive rebase or amended the commits, continued to commit some more code that modified that same part of the code, then on the next rebase you have conflicts because the commits that you have in your local branch that differ from the branch you are rebasing from are removed from the branch, the upstream is pulled in including that commit you've already pulled in and changed the sha1 of, and then when the commits are replayed onto the branch you end up with a conflict because the state of the code has changed from what the commit was expected because it was original created from a different history than what you now have on your branch. Wow, that was a long sentence...

    When you're "cleaning" up the pick list... what you are doing is likely deleting these repeated commits before rebasing, so now you're not reapplying changes that have already been applied, so no more conflicts.

    However, if you just wanted to resolve the conflicts during the rebase, this would likely be the best bet so you don't accidently delete a commit that you want. Resolving the conflicts will make the change set of that commit different an applicable to the history you have. Once you push this merge conflict resolution, you shouldn't see the issues again unless you modify commits that have already been pushed again.

    To find which files have the merge conflicts do:

    git status
    

    or

    git ls-files -u
    

    Once you know which files have conflicts, if you have a mergetool setup you can do:

    git mergetool <file>
    

    If you'd rather merge manually, you can find the merge markers and lines by doing:

    grep -Hnr '^={7}|^<{7}|^>{7}' *
    

    at the top level of your repo path and edit. When you edit manually, make sure you remove the markers and make the final version of the file look like how you want it to... git doesn't do anything special with the markers for you. When you've finished editting manually, make sure to do

    git add <file>
    

    to add the file to add it to the index and remove the unmerged flag. When you are done resolving all unmerged files, do

    git rebase --continue
    

    To complete the rebase.


    To get git rebase --continue to work you have to actually merge the conflicted files (edit them, pick the parts you want from between the conflict markers “<<<<<<<”, “=======”, “>>>>>>>”) and then git add them to the index (the index is where they are recorded as conflicted, adding a file clears its conflicted state). Check the current diff with git diff --cached , then git rebase --continue if it looks right.

    Before you attempt your rebase (or after aborting a problematic one), check out git log -p master..deploy to view the commits that you are trying to rebase. It is one of these that is conflicting with whatever you have in master.

    Those commits that you are dropping by deleting their 'pick' lines in git rebase -i might not be exactly the same (even though they have the same 'subject' in their commit message). The fact that you think there should only be one of them indicates that something fishy is going on with your deploy branch. Are these 'duplicate' commits at the tip of deploy or are there other commits after them? Maybe seeing the content of those 'fishy' commits ( log -p , above) will give you a clue as to their source.


    You could define an attribute in the parent directory of your "deploy-specific" files, in order to always select the content of the deploy branch in case of merge.

    For an example of merge manager, see this SO answer.

    Other strategies have been discussed, but the key remain: always consider a merge as "a project-wide merge" and not a file-based merge. Hence the attributes to refine that project-wide merge when it comes to some "special" files.

    链接地址: http://www.djcxy.com/p/42900.html

    上一篇: 在IE7或IE8中查看打印CSS

    下一篇: Git rebase不断失败,需要手动合并干预