Two of my friends create, extend and maintain ProvisionGenie. It's an awesome example of a beautiful application for provisioning Microsoft Teams teams, that does things right (using Power Apps, Logic Apps, managed identities, scripted deploys, etc.). I have the privilege of supporting Luise and Carmen on their journey, and sometimes I help out when it's out of their comfort zone.
Like when Luise noticed that Gavin Barron was not showing up in the list of contributors, although he had done 7 amazing commits:
This is of course unacceptable as ProvisionGenie wants to attribute, support and spotlight all of their contributors. This injustice had to be rectified!
Root Cause Analysis
Before you can fix something, you have to figure out why it is wrong in the first place. Enter Waldek Mastykarz! He started the Microsoft 365 CLI opensource project on GitHub, is now maintaining it with a group of core members, and he knows a thing or two about GitHub 😉.
His verdict: GitHub does not recognize the e-mail address Gavin used for his commits as a valid GitHub user and thus cannot attribute the commits to a GitHub profile.
It turned out Gavin made the original commits with an e-mail address that is not associated with his public GitHub profile. This is an easy mistake to make due to the nature of how GIT has to be configured, and I myself have also committed countless times using my personal e-mail address to professional repositories and vice versa.
GIT allows to have a global commit e-mail address and you can override this per repository. The trick to avoid this issue in the future is to set the correct e-mail address for a specific repository by using the command line in the root of that local repository, and run the following command:
git config user.email <GitHub email address>
First fixing attempt
Gavin tried to fix this using the information provided by Adam DeHaven using an interactive rebase. It worked but had two problems that we didn't like too much:
- The merge commits of PR's were squashed (and thus removed). This meant the resulting commit history had a couple less commits than before rewriting history.
- You pick a starting commit for the rebasing (by providing the SHA of the commit), and after the rewriting all commits after the starting commit got a datetime stamp of the rewriting. All original timestamps were lost.
Second fixing attempt
Building on the first attempt, I adjusted the commands a bit to limit the impact as much as possible.
Find the first commit to adjust
When doing an interactive rebase, you need the hash of the commit right before the one you want to edit. You can do this from the command prompt, from your favourite GIT GUI client, or from GitHub:
Start the interactive rebase
Open a Terminal that has the GIT command line tools installed and navigate to the local repository where you want to make changes (make sure it is up to date with the remote first, of course).
Run the following command (adjust with your commit hash):
git rebase -i --rebase-merges <commit-hash> --committer-date-is-author-date
Two adjustments to the command as opposed to what Adam DeHaven had:
--rebase-merges: keeps the merge commits in history, instead of squashing them. If you Google, you'll most likely find the suggestion to use
--preserve-merges. That parameter is deprecated and replaced with the newer
--committer-date-is-author-date: makes sure that the original date of the commit is kept when adjusting the author of the commit.
Decide which commits to edit
GIT will open your favorite text editor with the list of commits that happened since the commit hash you provided to the rebase command:
In this list you find all the commits that you want to adjust, in our case the 7 that were made by Gavin, and you change the
pick in front of them to
You leave everything else exactly as it is, you save and close the file.
Change the author of the selected commits
GIT will now start the rebasing and every time it gets to a commit that needs to be edited, it will ask you what you want to do:
This is one you enter the following command (in our case 7 times):
git commit --amend --author "New Author <firstname.lastname@example.org>" --no-edit && git rebase --continue
What this command does:
--amend the commit with new
--author information without doing a file edit (
--no-edit). I concatenate the command to continue the rebasing in the same action, to optimize and not having to enter two commands every time.
Force push the adjust local repository
This rewrites the history of the repository so if you want to push this to the remote on GitHub, it has to be a force push:
git push --force. All the usual cautionary messages around force pushing apply here as well, so beware of what this does and what impact it'll have on you and your co-contributors!
GitHub can now successfully recognize Gavin in the commits:
And thus also in the contributors of the repository:
The number of commits before and after are still the same, and they kept their datetime:
Only the dates of the impacted commits are changed in the GitHub commit history (even though the actual tree of changes is not impacted, so this is merely a visual thing):
Another, mostly visual, change happens for all commits after the commit hash you provided to the rebase command: in GitHub they get adjusted to "<original author> authored and <user that rewrote history> committed".
This has no impact on the statistics and the attribution to whomever did the actual work, so this is just a minor inconvenience for having Gavin show up in the list of contributors 😀.