问题
Please consider this scenario:
- I made a change of X number of files, pushed into
Gerrit
- Joe makes a change of Y number of files, Z of which intersect with my change set
- Joe's code review gets approved and gets merged into the remote branch, mine gets held in the code review stage
- Because Joe and myself changed a Z number of files simultaneously and his changes got approved before mine, I have to merge my changes into the Z files that Joe changed also
- I am in the same git branch I was in when I pushed into Gerrit and I have to be because that is the only branch that has my change ID which is the only link between git and Gerrit (to amend my existing Gerrit review, the amendment must be within the same commit, otherwise I would make a brand new branch and make everything easier but I can't do that because it doesn't have my change ID)
- When I do a
git pull
in that same branch, thefetch
part (remote->local) goes fine but themerge
part (local branch->working dir) fails because of the Z files that require manual merging. However, there are (Y minus Z) file changes that are not conflicted whatsoever. WHY DIDN'T GIT MERGE THOSE FILES AS NO CONFLICT SHOULD BE STOPPING IT? - I do a manual merge of Z files but now the staged git change set lumps them together with the Y minus Z changes that I have nothing to do with and shows them as modified/deleted in
git status
. They were modified/deleted on the remote, not local. If I do a commit, they will be included in the commit whereas I only want to include the Z files in my commit. So I can't really commit because if I do, all of the Y files will show and make it into the code review when they shouldn't, cluttering the code review.
Like I said in 5. above, I would resolve this contention by creating a brand new branch BUT I cannot do that because I won't have my change ID in that branch that I need to hook into the same existing Gerrit ticket.
The main two questions being:
Q1. How/can you make git merge the unconflicted files in the merge stage of the git pull while leaving the conflicted ones to be resolved manually? That way, once you are done doing the manual merge, you can do a build with the latest from the remote to make sure you can build before making any commits even locally. It seems to me this is a fundamental flaw with git (unless I am doing something wrong, e.g. not using some option with my git pull
)
Q2. Is there a way to push into an existing Gerrit review (amend it) using a different commit/change-ID from the one that was used to create the review initially? So far, the only answer I have been able to get to this question internally as well as on the internet is NO but to me that seems like another major deficiency. Because that Gerrit constraint, as explained above, limits you from utilizing the strongest feature of git, which is making local branches (in which you don't have that change ID) easily.
回答1:
To update your local branch with upstream changes, rebase your commit, don't merge. git pull
has a --rebase
option that you can use (and you can change your .gitconfig
to make it the default). Merging creates a useless merge commit that'll have to be reviewed, which doesn't make any sense – which you note yourself in #7.
Q1. This is a misunderstanding. Git will merge all files it can but ask for your help with resolving conflicts. I don't know what makes you draw the conclusion that those files aren't touched.
Q2. You seem to be conflating commit ID and change ID. The commit ID changes if you amend a commit (even if you don't actually make a change to the content of the files or the commit message) while the change ID is a Gerrit-specific identifier in the footer of the commit message. Gerrit uses it to connect commits with different IDs (SHA-1s) with changes in Gerrit. If you for some reason are unable to amend the original commit when you want to upload a new patchset for a change you can just add the Change-Id footer to whatever commit that you want to push.
回答2:
once a change has been pushed to review branch it can be fetched and modified without needing the original local commit.
So on FETCH_HEAD
branch you can merge/rebase the remote branch, amend it, and push as new patchset. That is it. So all commit has unique branch on Gerrit. And I think there is no sense pushing the amended commit with a new changeId. It would mean that the original one should be abandoned. With this technique codes can be shared with everybody and modified by everybody, without submitting the code to remote branch.
来源:https://stackoverflow.com/questions/20358933/git-pull-merges-no-files-if-any-of-the-deltas-are-conflicted-need-manual-merge