Azure DevOps - Cherry-Picking Into master branch - azure-devops

I have a scenario where I will sometimes need to cherry-pick some commits from our UAT branch into our MASTER branch. This is because the business sometimes will request that only specific "features" are moved from UAT to production. I need to be able to pick certain commits to move forward as PR.
The issue I am having is that when try to cherry pick from one the commits (from the UAT branch) to master, Azure DevOps give me the error...
"Encountered conflicts when cherry-picking commit "42af19". This operation needs to be performed locally."
I am able to do this same pattern against my UAT, QA and Integration branches, I only have this issue against our master branch. I don't have any conflicts in the source branch so I don't believe its that. I also don't have any special rules for the master branch that should keep me from doing a UI based cherry-pick.
I really can't have our developers do this locally so I am hoping for some sort of option where they can use the UI for this.
We are using ADO to host the repo for our Salesforce code. We use another system that handles the CICD pipeline.
The high-level background for this is that we have may have 2 or more PR's that have been promoted and deployed to UAT, but the business may request that we only deploy certain ones. So some PR's might remain open against master for a few dev cycles. The issue is when other PR's move through and we need to promote them from UAT to master, ALL of the changes are getting added to the UAT > MASTER PR due to the fact that the code in the PR's that are in the holding pattern have not been committed to master, so the subsequent PR's would pick up those changes and try to merge them in, and we don't want that.
The thought is that we could cherry-pick commits from UAT as a PR. These only only contain the files we actually want to deploy, not EVERYTHING.
Hopefully someone can help me out with this scenario as I am a little stuck.
Thank you all very much for your guidance!

I have been working with a similar branching strategy for Salesforce. Normally in this situation, we would do the following:
Create a branch out of master - it will be used only to resolve conflict.
git checkout -b gs-pipeline/...
Cherry-pick a commit there, you can space separate them if there are many
git cherry-pick COMMIT-HASH1 OPTIONAL-COMMIT-HASH2
Solve Conflicts manually, save files, stage them, commit and push
Open Pull Request from gs-pipeline/... -> master
Unfortunately, there is no easy way to solve this within UI as far as I am concerned.
However, when you would down merge from master -> uat(directly or via a separate branch) that may solve your issue. It should be safe as things on master/PRD should already be on UAT and all lower environments.

Related

Can I require that pull requests to a certain branch on github be squashed?

Github has the option to allow a PR to be squashed when merged ("Squash and Merge")
Is there anyway I can configure the branch so it only allows the "Squash and Merge" option?
My scenario is this
we have a develop branch, that feature requests are pushed to
sometimes developers will forget to choose "Squash and Merge" and will commit their feature branch, with 10-20 tiny commits to the develop branch.
These changes eventually get merged to master, and feature history becomes hard to read
I have looked in hooks in branch protection rules, but didn't see any such option
Unfortunately the option to change what type of PR merge is available on Github is set on a per repo basis. Since PRs are a github thing, not a git thing, I can't think of a way that you'd be able to do anything with githooks either.
I don't see a great option for your workflow as long as you require the intermediate develop branch that eventually gets merged into master. Workflows that have multiple layers of PRs get messy on Github. The one real option would be that you require squash to merge on Github PRs and then the regular merge from develop to master happens outside a PR (could be local on a machine or via a Github action potentially).
But, your best option if this is really a big problem may be to modify your workflow. One common workflow would be that master is the development branch. Then when it is time for a release a release branch or tag, depending on your needs, is created from master. The you will have no issue turning on the repo wide requirement for squashing.

Cherry pick or selective merge from dev branch to prod

I have deployed Azure Data Factory pipelines and associated components to adf_publish branch in Azure Devops. Now I want to deploy those changes to the Prod branch, but the problem is that the Prod branch and adf_publish are not in sync. When I try to create a pull request I get 100 files and 100+ commits will be merged message which is not what I want. I want to merge only 1 Data Factory pipeline which was newly created and associated datasets (8) and Linked Service(1).
I tried the cherry pick method from the adf_publish branch but it still takes everything that is missing from Prod Branch. Is there an easy way to accomplish this either through the Azure Devops UI or through Visual Studio Code.
As per the screenshot below I see + next to multiple pipelines which indicates that they are not present in Prod branch, I just want to merge 1 pipeline and leave all the rest in adf_publish.
Any help would be highly appreciated. I have tried multiple things but nothing is working. Thanks
ADF_Publish branch will generate ARM templates for deployment automatically. Those templates you will be selecting as part of your release pipeline to perform deployment.
So, after merging ARM templates from ADF_Publish branch to another branch, if you are using same ARM template files from another branch to release deployment then it should work.
If the change(s) you seek aren't in separate commits, break the commit into individual commits using the approach outlined here. You use git rebase -i to obtain the original commit to modify, then git reset HEAD to selectively rollback changes, and finally git commit to commit that part as a new commit in the history.
Another useful technique is described in Red Hat Magazine, where they use git add —patch or maybe git add —interactive to add just sections of a hunk if you wish to separate various changes to specific files (search in that page for "split").
After splitting the modifications, you may now pick and choose which ones you wish.

Github develop branch merge to master showing more history than expected

Been using production/integration branches to manage code promo to production. Our integration branch is a stable integration environment that all feature branches are made from, and merges are reviewed by PR, and deployed via CI when approved and squashed+merged. Once integration is stable and we've tested it, we do another PR from integration to production. When this is approved and squashed+merged, CI takes over and deploys to the production env.
git checkout integration
git checkout -b feature
# do work
git add/commit etc
# create PR, squash+merge on github UI when reviewed
# CI sees new commit to integration, deploys to int env
My issue is with what these integration -> production PRs looks like when they are reviewed - even though (at times) I've done the following to get any commits already in production into integration:
git checkout integration
git pull
git pull origin production
git push
# create PR for integration merge into production
When I go look at the PR page on Github, the list of commits shows history going back to commits that are already represented in production. The "Files changed" list is very small, while the commit history goes back many PRs ago. I thought git pull origin production would remove this history and then only show the new commits coming from integration to production?
Am I missing some obvious way to maintain merge commits but also clean up the history when integration is merged into production? Could inconsistent merging/rebasing strategies cause this?
Some screenshots to show what is confusing - a PR that has a single file changed from a single commit, but the commit history goes back much further:
The single file change was the last commit in the list—why does the PR show commits that have already been merged previously? I thought Squashing and Merging (both into integration from feature branches and into master from integration would remove this commit history and make merges into master clean?
The green arrow represents the 1 file changed in this PR, and I thought the commit history (after a merge of production back into integration to clean the history, if any) would only have that one commit.
Is this a github display bug or am I missing some principle of how git maintains commit history across a long-running branch that gets merged into another long running branch? It's always a one-way merge, from integration into production branch, for CI to deploy the update.

How to do hotfixes with GitHub Pull Requests

Caveat: I am fairly new to both git and GitHub.
So, in my current setup, my team uses git flow Hotfixes (usually started and finished by a graphical tool such as GitKraken or IntelliJ) to make changes that have to be merged into two branches and pushed upstream in both. So for example the flow would be:
Pull latest from master
Start hotfix
Commit changes
Merge hotfix branch into both master and develop and push both upstream
We're now looking at moving our code into GitHub and would like to start using Pull Requests, for a couple of reasons:
CI hooks to run tests and stuff
a place to put code-specific comments not directly related to the underlying "issue"
avoiding the need for everyone to constantly be pulling the latest master/develop to their local machine so that they can merge changes
But in the case of Hotfixes, I'm not sure what to do because I'm merging into two branches but it really is one "action" so manually creating two pull requests seems weird, particularly since step 4) in our current flow is a single click.
Is there a smart way of handling this? My ideal case would be that pushing the Merge button on the Pull Request would just merge into both, but that doesn't seem to be an available option.
As you mentioned, a Pull Request has only one target branch, so you won't be able to push the hotfix to both master and develop by merging one Pull Request.
I'm also surprised you mention your step #4 - merging the hotfix branch to both master and develop and push upstream - is one action. While there's a high chance the merge from hotfix to master won't run into merge conflicts, I can't say the same for the merge from hotfix to develop since it could have been worked on since the last deployment to production.
My recommendation would then be the following:
Create one PR from hotfix to master and have someone review it to validate the fix
Once it's merged into master, create another PR from hotfix to develop and see if you run into merge conflicts
If that's the case, resolve the merge conflicts so the PR ends up in a state to be merged, and have someone review the PR
If there's no merge conflicts, then have someone review the PR
An alternative solution, if you really want to go down the automated path, would be to leverage both GitHub webhooks and API.
The webhook would allow you to be notified when a PR is merged. You could inspect the payload to make sure that the base branch starts with hotfix/ and the target branch is master. You could then react to that event by using the API to create a new PR from the same hotfix branch to develop.
It will involve some development, and the effort might not be worth since creating a PR via the UI is still quite easy and quick.

Git conflicts in pull requests

I have 2 branches - master and develop
I have been doing some pull requests in my develop branch where it contains 5 items, in which it is the same as the number of items in master.
However, someone did some commits and pushed in a few more items into the master branch, and hence now it has 8 items.
As my pull request in the develop is still not yet approved/merged, whenever I tried to update my pull request, I am getting the message stating that This pull request can't be merged. You will need to resolve conflicts to be able to merge and asked me to do the following:
git fetch origin master
git checkout develop
git merge FETCH_HEAD
git commit
git push origin HEAD
And this happens after I have 'pushed' out my commits, making me confused at times. Then I realized that it is asking me to re-add and re-commit in the additional 3 new items. So does this means I must ensure that the items and contents between these 2 branches of mine should be the same as always? I have always used git pull/fetch but will there be a better way for me to make sure?
What this means is that GitHub would like to merge your PR branch into master, but it can't, because there are conflicts. As you've discussed in the question comments, the best way to deal with this (usually) is to merge your master branch into develop on the command line. That will show you the conflicts and ask you to resolve them. Once you've completed and pushed that merge, the PR will be mergeable back into master using the green button on GitHub.
You could simply merge your deploy branch into master (which I realize sounds a bit more sensible). In that case, you'd be bypassing the PR entirely. You'd have to close the PR "unmerged", and separately you'd manually push the merge commit to master.
By doing it the first way,
you make a better audit trail by merging to master on GitHub, using the PR;
you give your team a chance to review your code after the merge, before it lands on master; and
if you have automatic tests (such as Travis CI or CircleCI) which check PRs, you give them a chance to run your merged code as well.