How to work multiple pull requests to a single GitHub project? - github

Let's say that for a single GH repo I have changes to file A, and unrelated changes to file B.
Since the changes are unrelated, they don't belong in the same PR.
Suppose I do this:
Push change A to branch a.
Push change B to branch b.
Wait for comments/approvals for both.
When one, say A, is approved and merged, won't that foul the merge for B (which does not have change A)?
If so, is there a workflow where I can have PRs for multiple branches that will work?
Thanks for any help.

If you have changes in separate files, then those changes aren't going to have conflicts. It's possible to have multiple pull requests open for non-conflicting changes at once and have all of them be merged successfully. This is true whether those multiple merges come from one person or from multiple.
In fact, this is part of why many version control systems (like Git) exist: they allow multiple people to collaborate on mutually independent changes at the same time and include them via merges as they become ready.
So you should end up with no problems with these multiple PRs if they really touch only independent files, or even if they touch the same files but have no conflicts.

Related

What constitutes a "branch with too many changes" for Github PR rebase merging?

What criteria does Github use to determine whether or not a given PR "has too many changes" for rebase-merging?
I've worked on a refactoring effort recently and after submitting and getting approval in the PR, I got the following message from Github's UI, preventing me from rebase-merging the change:
This branch cannot be rebased due to too many changes
At the time, I had no idea what exactly the limit was, so I split my ~30-commit PR into 2 ~15-commit changes, which made the restriction go away.
I found a question around the same limitation, but it doesn't focus on what these limits are, asking for workarounds instead:
This branch cannot be rebased due to too many changes
I'm now doing another change which also has a similar number of commits and wanted to know exactly what rules Github uses to determine whether or not a given PR "has too many changes" so that I can split my PRs accordingly upfront and avoid rework both on my end as well as on reviewer's.
I tried finding official documentation on this to no avail. Unfortunately, the only way I'm aware of to test it is to submit the PR and check if the message comes up. This however becomes unfeasible since the message only shows after all checks have succeeded, meaning I have to also get actual reviews on the change to check whether they are mergeable or not. If I then find out it is not mergeable, I have to create a separate PR and split the change, wasting everybody's time on re-reviews.
Many different aspects (or a combination of multiple aspects) could be the cause for this:
Number of commits
Number of affected files
Number of affected lines
Number of conflicts with base branch
etc
I've been using GH for a long time and had never seen this message until a couple weeks ago, so I assume it is either some new feature, or maybe a restriction depending on the type of plan used by my company.
This is almost certainly a timeout-based situation. GitHub uses libgit2 to perform rebases and how long a rebase takes depends on the number of commits, the complexity of the changes in each of those commits, and the complexity related to the repository (size of objects that must be looked up, etc.). libgit2 doesn't have all the optimizations of regular Git, but regular Git cannot rebase in a bare repository, so the use of libgit2 is required.
So there's no fixed limit in the number of commits or the complexity, only that if it takes longer than whatever the timeout is, the operation will fail, and you'll be left with that message. One way to avoid this is to use regular merge commits, which while not immune from timing out, are less likely to do so because the merge involves only three commits, not however many are in your branch.

Deleting draft PR's

I know github generally has a rule where PR's and stuff can be closed, but never deleted to preserve history, unless there is something very necessary about it (such as private keys being included in the PR by accident, etc.). I was wondering, however, if draft PR's can be deleted. Sometimes I use it for certain CI/CD testing, and I end up closing them, but they can start cluttering up my PR history. Since they were never converted to a full, real PR, is that a thing we can do without contacting github support?
Thanks!
Apparently no. Draft PRs are treated like regular PRs and cannot be deleted without contacting support. https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/removing-sensitive-data-from-a-repository. They only delete them if there is sensitive data.
You might want to setup a separate repo just for CI/CD testing if you are trying to test configurations like Actions. That would keep your main repo from getting cluttered.
If you are creating draft PRs to run tests, that could indicate your tests are difficult (or slow) to run locally. I'm just assuming though. I know that's why I sometimes reply on CI/CD instead of local testing.

How to merge several branches into master with one pull request, been able to undo just one later in github

I am working on a project with a legacy codebase that has basically no automated testing and no testing environment, so the only testing possible is in my local environment with no testing input data and no output test cases.
During the week we merge the branches we finish into one week-merge-day branch using pull requests, and that branch is merged to master once a week using also a pull request. The problem is that, given the poor testing scenario, it is common to need to undo the week merge because one of the branches is causing the production version not to be usable. Of course, this merge undo restores the master branch to the previous state, undoing the merge of all the branches merged, not only the wrong one.
How can I handle this situation when I have to merge several branches at once and, later, undo the merge of only one of them?

Counting commits per developer using webhooks

Using Github webhooks, what is the best way to count the number of commits by a developer for a particular piece of work.
I was thinking that I could do like this:
Listen for webhooks pertaining to merges of any PR into the main branch
discard the webhook event unless it pertains to the main branch
if the PR merge is into the main branch, then find out all the commits (and developer-related to each commit) related to that merge and calculate a count
are all these commits(and developer usernames) even listed in the webhook event?
Will the commits related to the merge definitely only be comprised of commits after the branch was created up until its merge.. or will they actually go all the way back to the beginning of repository creation?
Had also considered listening on webhooks related to "Tag" type pushes, but would a new tag event be able to tell me about all the commits between that tag and a previous tag.. probably not right? I'm guessing that whatever the tag is that it would always represent all commits from the start of repo creation
You can use roughly the approach you've outlined. You can extract the base and head revisions from the desired webhook events and then run git rev-list --no-commit-header --format=%aE $base...$head to find the email address associated with each commit. (You can use git log instead of git rev-list --no-commit-header if you're using an older Git).
That will count only the commits that were created in the branch and are not otherwise merged into main. Note that if you're using squash merges, this doesn't work because the merge base doesn't update; I recommend not using squash merges anyway. In the case of a squash merge, the number of commits created is always 1. You can tell whether a squash merge has taken place because git merge-base --is-ancestor $head main will exit 1; that is, the head of the PR branch is not an ancestor of the most recent main.
While this will work to count the commits per developer, I should point out that counting a developer's commits is not a good measure of productivity and shouldn't be used as a performance metric. A developer may be highly skilled and write only a single commit after investigating a difficult problem, but counting commits would rank that person lower than someone who fixes many easy problems. There are also other skills, like communication and collaboration, which cannot be measured in commits.

Mercurial hook to list outdated branches which are behind their parents

We use mercurial workflow with one stable branch (default), one unstable (develop) and feature branches. We want feature branches to always contain all changesets from parent branch(es) to simplify merging them back. Is there any example hooks to prevent adding commits to feature branches which are behind their parent branch? Github has a similar message when your branch is behind master.
Generally there are two scenarios:
Enforce feature-branch owners to sync with upstream branch before pushing new changes (pushed changegroup should be not behind its parent)
Periodically check for list of child branches which became outdated due to recent commits in their parent branches and nudge branch owners to sync or close it
It's basically two separate things you ask:
There is no pre-made hook for denying push when not merged with default which I know of, but maybe some google-foo might reveal some. However it should be quite straight forward to create one:
By my understanding of your requirements: you want to check an incoming transaction to contain only commits to the non-default branch, if their latest commit is a merge of default into it. This is a task for a server-side hook of the pretxnchangegroup kind; there you can analyse the incoming transaction and the changesets it contains and reject the transaction if it does not meet your requirements. Therein check the latest commit to a feature branch (or better non-default and non-develop(?)) to be a merge commit with default or develop.
As to periodic checking with the central repository:
The periodic checking for outdated child branches is a client-side action. You could for instance create here a commit hook. Thus querying hg incoming each time a commit is made. Or simply make a crontab entry client-side and trim the output to your desire.