pick conflicts between diverged branches without committing

I got two branches (master and feature) that diverged.

master  - C1 - C3
            
feature      C2 - C4 - C5

C2 and C4 are just dirty commits with temporary code, that I don't want to have into the final merge/rebase of the two branches.

I usually perform a:

git checkout master
git cherry-pick C5 (last commit from the feature branch)

But this time I have C3 that conflicts and I cannot pick the commit.

What I tried is rebasing C3 into the feature branch, so to not have conflicts when cherry-picking.

git checkout feature
git rebase master

Now I got this

master  - C1 - C3
                
feature          C2 - C4 - C5

Seems fine, but if I try to cherry-pick again onto master I still get conflicts (on some empty space I removed from some files).

Git is telling me to resolve the conflicts, to add the files, and commit. I can solve the conflicts manually, but don't want to commit them just as a conflict resolution.

I want to avoid commits in my history about something that is not related directly to implementations. I would not even know what to write as commit message.

  • Why I still get conflicts after the rebase?
  • And how can I get C5 to be merged/cherry-picked to master without additional commits?
  • I usually prefer to cherry-pick cause I can avoid the 'useless' merge commit and have just commits regarding code changes. Then after that I delete the branch, after a while I'm sure I don't need it anymore

    [[ EDIT ]]

    The wierd behaviour is that C5 and C3 conflict on files that are not changed on C3.

    Infact, all the detected conflicts are just empty on the master branch

    <<<<<<< HEAD
    =======
    [ added code ..................... ]
    [ .......... from ................ ]
    [ ............... 'feature' branch ]
    >>>>>>> 581g52d... "Commit message from 'feature' C5 "
    

    What I need to 'solve' is just deleting the conflict tags from the conflicting files.

  • I don't get the reasons of the conflicts
  • I would like to solve it manually and then merge/cherry-pick without having to create a new commits
  • cause the commit will just solve some conflicts with a branch that in the future will be deleted
  • when deleted the branch, that commit will have no sense/position in the repository history
  • [[ EDIT 2 ]]

    Moreover, if I try to `git cherry-pick master/C3 to feature I get:

    no changes added to commit (use "git add" and/or "git commit -a") The previous cherry-pick is now empty, possibly due to conflict resolution.

    I don't get why I have conflicts in the opposite direction (from feature to master)

    [[ EDIT 3 - Retrying from the beginning! ]]

    Here is what I tried too.

  • Made two copies of the master branch, with C3 as last commit, named: master_copy and repeat_feature

  • git checkout master / git branch master_copy / git branch repeat_feature
  • Cherry-picked every commit from the feature branch, until C5, into repeat_feature
  • git checkout repeat_feature / git cherry-pick C2^..C5 (from feature)
  • (I got NO CONFLICTS )
  • Tried to cherry-pick C5 into master_copy, from repeat_feature
  • remember that repeat_feature was started from C3 (so, if there were some conflict, those should be raised while cherry-picking from C2 to C5)
  • git checkout master_copy / git cherry-pick repeat_feature_C5
  • I still got the same conflicts!

    Even if I was starting from the same C3 commit (when cloned the branch to repeat_feature branch) and trying to cherry-pick to the same C3 commit (into master_copy)!

    I totally don't get the point of what's happening and why I get these empty conflicts that prevent me from moving my feature to the master branch.

    An expert's suggestion is needed here.


    I finished to change approach:

  • I made a copy of _feature_branch_ ( git checkout feature_branch / git checkout -b copy_feature_branch );
  • I 'compacted' all the branch commits into a single one
  • first: I come back to the parent commit of the branch: git reset <branch_parent_commit>
  • second: I re-add all the changes with git add . , and then commit with git commit
  • finally I cherry-picked this commit into the master branch, applying al my changes from the feature_branch with just one commit (as I wanted to do with C5, misinterpreting git cherry-pick). git checkout master / git cherry-pick <last-commit-of-copy_feature_branch> )
  • This way I get no conflicts at all (as I would expect to happen) and I obtain to have just one commit that introduces all the changes (or anyway a 'packet' of changes) from the feature_branch. I made a copy of my feature branch so I can have for a while the full sequence of WIP commits, that could be useful to have for a while (for testing, apply fixes, see the history of the changes for the specific feature). Instead of deleting the branch I usually rename it with git branch -m <current_name> FINISHED_<current_name> and keep it until I'm not sure I want to delete it.

    It is not a wonderful workflow but actually it's working for me, waiting to find a better way to accomplish my needs.

    Unfortunately I still cannot explain the specific logic causing the conflicts when cherry-picking just one last commit (partial change from the feature). I know that I was doing wrong, but don't know how that conflict on those specific file-parts was coming out.


    I want to avoid commits in my history about something that is not related directly to implementations.

    As I read a plenty of answers on this topic on SO , I could say that most people advise against using unneccessary git cherry-pick .

    Yes, cherry-pick is not for merging something, that've been developed trough a bunch of commits. It's for applying small changes from one branch to another for codelines that both branches have not changed in their other commits.

    The main possiibility is to merge feature C5 state to master while avoiding some dirty C2 and C4 is to use squashing.

    1. Using merge :

    git checkout master
    git merge --squash feature
    

    2. Using rebase :

    This could be done with interactive rebase:

    git checkout feature
    git rebase -i master
    

    Then, you should change pick to squash for all commits besides one.

    Also, start all of your temporary commit messages with squash! or fixup! word. Then you will be able to use autosquash (all temp commits will appear with this keyword on the list during rebase)

    git checkout feature
    HASH=`git merge-base --fork-point master`
    git rebase -i $HASH --autosquash
    
    链接地址: http://www.djcxy.com/p/26084.html

    上一篇: Git:将多个提交从一个分支合并到另一个分支

    下一篇: 在没有提交的情况下挑选分歧分支之间的冲突