gitgit-cherry-pickazure-devops-server-2020

Merged conflict cherry-picks still show as not merged in git cherry output


tldr; Cherry-picking commit into another branch where a conflict exists, requiring manual resolution in a new branch, causes the original commit id to not show in the git -cherry -v output. How can we get the commit id to show so we know the fix was applied to a branch?

I'm trying to determine whether a pull request on main was merged into a child branch. There is more to it but let me first give you the setup of our system.

We are using Azure DevOps Server 2020 along with git. Our branching is set up with three core branches, main, preRelease, and currentRelease, with all feature and bug branches being created off of the main branch. Once a work item (i.e. bug or feature) is verified as passing all tests, each pull request associated with the work item gets cherry-picked from main into preRelease.

This setup works well for cherry-picked pull requests that don't have conflicts which require a manual reconciliation of the changes. We are able to use the git cherry -v origin/preRelease origin/main command to see which commits and pull requests exist between the two branches. We can then filter out all cherry listings that start with a - and then check the status of the work item associated with the pull request id to determine if it is in a state where it should be merged into the preRelease branch. The branches that were already merged are filtered out because they start with a + in the git cherry output. What is seen when there is a cherry-pick that has conflicts is that the connection back to the original commit and pull request is not available and not updating the log output from the git cherry command to show the commit was merged.

I thought that the problem might be how we are completing the pull request when we merge it into the preRelease branch. However, attempting the different options in DevOps, Merge no fast-forward, Rebase fast-forward, and Semi-linear merge, all resulted in the commit not showing up as a part of the preRelease branch. This leads us to believe that the work item isn't part of the branch when in fact it already is incorporated into the code.

So my question is whether it is possible to utilize git and the Azure DevOps Server 2020 API to determine whether a commit has been merged into a branch via cherry-pick, even if it was merged by a new branch because of merge conflicts. If there is a better way to handle this whole process I am open to it. I am by no means a git or DevOps guru. If the cherry-pick process we have for migrating updates between main and preRelease is the way to go then is there a way to trace back the original commit from a cherry-pick that required a new branch to be created for the handling of merge conflicts. Note, when we create a branch to handle the merge conflicts we start in the preRelease branch, pull down the latest code, then create a new branch off of preRelease and execute a git cherry-pick <commit id> to pull down the code for merging. Also tried git cherry-pick -m 1 <commit id> but didn't see a difference in the resulting commit logs to show the original commit id.


Solution

  • git cherry won’t find the commit since the commits introduce different changes.

    Suppose you cherry-picked a commit that appended ten lines to a file. But then you tried to cherry-pick it onto a history where three lines had been applied to the same place. So you resolve the conflict. But the changes from the original commit and the new commit are different now since those three lines are different. So git cherry compares their changes (a simplified version of the diffs) and the comparison fails.

    Cherry-picks are way too brittle to rely on for propagating changes from development to prerelease and to release or whatever have you. Use merges instead.