Table of Contents
Back to [ProvideFix How To Provide A Fix].
Dealing with rejected patches
It can often happen that a patch you submitted to the Patch Manager gets rejected by our benevolent dictator, especially if you're a new dev and you are not that familiar yet with the rasdaman coding guidelines.
In case you are not familiar with git
neither, here's a couple of examples of possible solutions that apply to such situations.
SCENARIO: you formatted a patch pZ
for commit Z
in your local branch my_branch
on top of A
.
The master
branch is a clean and synced copy of the origin/master
remote branch, hence the public HEAD of rasdaman:
o-------o-------A-------B-------C [master] -> [origin/master] \ \ X--> rejected! \ /-pZ Z [my_branch]
This is usually a recommended developing workflow, so if you worked directly on your local master
, you might want to switch to this layout:
$ git stash $ git checkout -b my_branch master $ git checkout master $ git fetch origin $ git reset --hard origin/master HEAD is now at `D' <ticket:XYZ - Brief description of this patch> $ git branch * master tmp
Now the local master
is synced with the patches that surely in the meantime were accepted in the Patch Manager.
The other (local) branch my_branch
contains your rejected commit Z
.
At this point there can be possible solution in order to rework on the patch:
1. [Rebase &] amend
If there are not patches which were applied since your rejection (ie B
and C
, see above), you can avoid rebasing: your my_branch
branch is still on top of origin
's HEAD.
Otherwise firstly you can move my_branch
on top of D
:
o-------o-------A-------B-------C [master] -> [origin/master] . \ . \ Z --(rebase)--> Z [my_branch]
Afterwards, you can amend your commit: you can simply do it by modifying the files you are required to — also files not previously included in the Z
commit, stage them, then re-commit with the --amend
option. You also have the chance to change the title of your patch during the process, eg Z~
$ vim file1 file2 ... fileN [do your stuff] $ git add file1 file2 ... fileN $ git commit --amend [you can change the title here now through your configured $GIT_EDITOR]
o-------o-------A-------B-------C [master] -> [origin/master] \ \ Z~ [my_branch]
Now you can reformat the patch:
$ git format-patch HEAD~
0001-Z~.patch
Look out there are no other new patches in origin
:
$ git fetch origin
Otherwise you can also try to see if your patch does not conflict with new ones: for instance while you were fixing your patch, a new one (D
) was accepted:
o-------o-------A-------B-------C-------D [master] -> [origin/master] \ \ Z~ [my_branch]
Instead of re-rebasing, you can try:
$ git checkout master
$ git merge origin/master
$ git apply --check 0001-Z~.patch
If no output is printed, then you can submit the new patch: http://rasdaman.org/patchmanager.
2. Cherry-pick
An other possible solution, which might be easier in case your rejected patch has already been followed by tons of other patches you formatted and that were accepted, is cherry-picking.
For instance, a patch pZ
(for your Z
commit) was rejected, then a new patch from some other dev was accepted (B
), and an other patch you developed afterwards on top of Z
was accepted (patch pW
for bringing local commit W
to the public repo as W~
):
o-------o-------A-------B-------W~ [master] -> [origin/master] \ /----> accepted \ X-------/-----> rejected! \ /-pZ /-pW Z-------W [my_branch]
You can clone your master to a new branch and cherry-pick your Z
but without creating a new Z
commit, just taking its changes:
$ git checkout master $ git fetch origin $ git merge origin/master $ git checkout -b my_other_branch master $ # Pick Z (refs/heads/my_branch~): $ git cherry-pick refs/heads/my_branch~ --no-commit $ git status [changes in Z are staged now]
o-------o-------A-------B-------W~ [master] -> [origin/master] \ \ \ o-(c-pick)-(Z~) [my_other_branch] \ / Z-------W [my_branch]
This way you can now fix the changes, re-stage them and commit.
2A. Cherry-pick cleaning local master
Assuming (use export to set them in bash):
rejcomm=sha-of-your-rejected-commit lastgood=sha-before-your-rejected-commit
#branch from last good commit git checkout -b re-patch $lastgood #cherry-pick rejected patch to be fixed, without committing it git cherry-pick $rejcomm --no-commit #Amend the files, stage them with git add, then commit and create the new patch geany fileToAmend git add fileToAmend git commit -m "old message /vN" #with N=2 to be incremented just in case git format-patch HEAD^ # Works only with single last commit # Now you are left with the rejected patch still committed on the master # and the "hopefully to be accepted" patch in your temporary branch # A practical way to avoid merge conflicts and let you merge your branch # and pull from master is to: # Revert the rejected patch on your master git checkout master git revert $rejcomm #merge your re-patch branch (should go without conflicts, if not see note) git merge re-patch
- NOTE: If you have more than one related commits (depending on) to the reverted patch (perhaps also to be amended), you can cherry pick also these to the branch and revert them in reverse order on the master.
- NOTE2: Still not know what to do if the dependent commits are from other authors (should not happen since the patch was not accepted) but I guess the method still applies as long as you add a patch taking care of such dependent commits.
3. Brute force procedure
The following procedure ensures resolution even if you did not keep the patch branch in your local repo or would have a complex rebase due to subsequent local patches. Using a branch for each patch and rebasing it has to be preferred as a best workflow.
- clone the repository from scratch (optional, also a new branch should do)
- apply the patch manually (with
--reject
option) git apply --reset patch_file
- fix manually the rejected files
- You can find them by their extension (
.rej
) - then generate a new patch
I think the only problem with this approach is that such patch won't be into your main working copy (existing repo), hence a clash might occur at next git pull
.
Final note
Conflicts can always happen, it's not your fault.
https://duckduckgo.com/?q=git+rebase+conflict