Gh Elao🔗
gh-elao is a tool for Github for the internal Elao Git flow.
It:
- merges Github PRs from command line in an interactive way
- keeps up-to-date your local branches before merge
- warns you if you're trying to merge a PR for which CI checks are failing or not run yet
- automatically squashes PRs with multiple commits
- formats merge commits in a meaningful way
- helps generate changelogs
- merges a PR in another branch, without closing the PR
- thanks your teammates for their awesome work 💖
Installation🔗
The tool is provided as a standalone static PHP binary (using static-php-cli).
Install it using:
1 |
|
which should setup the gh-elao
binary on your system.
Tip
The binary is also available as a git
command.
Either use gh-elao <command>
or git elao <command>
.
This documentation will always uses gh-elao
for consistency.
Try executing gh-elao
from your terminal. You should see configuration documentation as well as the available tool commands.
The simplest way to configure for all project at once is to use:
1 2 3 |
|
Note
You may already have a github.token
.
Otherwise, generate one at https://github.com/settings/tokens/new with repo
permissions at least.
Gitignore files generated by the tool🔗
The tool relies on creating some temporary files on your filesystem to store notes & detect transitory states (e.g: when resolving conflicts during a merge) so you can continue the process where you left it. These files can be annoying and should never be merged, so let's ignore those globally:
1 2 3 |
|
Update🔗
Re-execute the installation command to update the tool.
Formatted merge commits🔗
Instead of the Github default merge commit format Merge pull request #PR_NUMBER from BRANCH
,
the tool merges PRs using a meaningful message: [hash] category #PR_NUMBER PR_TITLE (author)
,
were:
hash
is the merge commit hashcategory
is one offeature
,bug
,minor
orsecurity
#PR_NUMBER
allows to jump to the original PRPR_TITLE
is the PR title the developer should carefully chooseauthor
is the one(s) with commit(s) in the PR
E.g: bug #1008 Fix homepage header (ameliedefrance)
These merge commits helps generating a changelog between versions.
Generate changelogs🔗
The following command helps you generate a changelog between versions:
1 |
|
E.g:
1 2 |
|
This command is actually a proxy to a git alias you can add to your own git config (the command shows it to you)
Tip
OS X users: use pbcopy
to copy/paste the changelog to your clipboard:
1 |
|
Merge a PR🔗
Merge a PR using:
1 |
|
An interactive prompt will start, checking CI tasks, asking whether to squash commits, the category (feature, bug, ...), ...
The PR code is merged into the target branch with a formatted merge commit. You don't have to checkout nor fetch the target branch. The tool will do this automatically for you. When the merge is done, your local current branch is the one targeted by the PR, up-to-date, allowing you to perform a release directly if you need to.
Warning
Some considerations
while it doesn't require you to keep your local branches up-to-date, any commit you have locally on the target branch that is not present on remote will be pushed. This allows you to tweek a PR right after merge and before pushing it to the remote. But this can also lead to unexpected commits to the targeted branch. First rule: do never commit anything on targeted branches directly. I.E, typically: don't commit changes on your local master
or staging
branches unless you plan to push it.
Understanding the merge process🔗
The tool is nothing but a wrapper around git + Github API. Whenever you're trying to merge a PR, the tool:
- fetches the PR locally using
git fetch origin pull/ID/head:pull/ID
(see https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/checking-out-pull-requests-locally) - checkouts the targeted branch (e.g: master)
- pulls
master
changes from remote - rebases the PR local branch to the target: at this point, you might have some conflict to fix. Re-run the command to resume the merge once all conflict are fixed.
- merges the PR into the target branch locally using
git merge --no-ff
once you answered everything - ask you if you want to push the changes right now or not. This step allows you to add some more commits before answering yes (or answering no and pushing manually)
Merge a PR to another branch🔗
The tool is especially useful in scenarios in which you want to merge a PR to another target than the original one.
E.g: a PR is made on master
but required to be merged to staging
first for client review.
Merge this PR to another branch using:
1 |
|
E.g:
1 |
|
The PR code is merged into the new targeted branch, while the PR is still open, allowing you to merge to original branch later.
E.g: Whenever the client approved the PR on staging
, merge to master
.
Tip
Since it's not much useful to thanks your teammates when merging on staging for client review,
and since it might get merged multiple times before being validated, you can use the --no-thanks
option.
You may also want to register aliases of your own. E.g:
1 |
|
Merge new commits from a PR🔗
In the previously mentioned --switch=staging
scenario, the code might need some changes after client review.
The simplest way is to append a new commit and run the tool again:
1 |
|
Git will automatically detect already merged references and ignore those, merging only the newly appended commit (do not use squash). In case the PR was rebased in between, the commit hash differs and conflicts might have been solved in-between. Git is unable to detect the patch was already applied for those commits and will try to merge them anyway, leading to such errors:
1 2 3 4 5 6 7 8 |
|
See full error
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
|
This error indicates you multiple ways to fix the issue:
- either by fixing conflict
- either by skipping the commit
As we for sure know this commit is already merged, the second solution is the right one. Use git rebase --skip
for each of the already merged commits. Then, re-execute the same tool command line to resume the merge.
For ref:
- No changes -- Patch already applied
means the commit changes are properly detected as already merged and causes no issue, skipping the commit automatically - Applying: commit 1 [...] CONFLICT (content): [...] Patch failed at 0001 commit 1
means the commit is likely to be already merged and should be skipped usinggit rebase --skip
- Applying: commit 3 with no more hint means the commit was successfully merged
Handling conflicts🔗
Conflicts can be handled directly while merging. When you get such an error:
1 2 3 4 5 6 7 8 9 10 11 |
|
the merge process is interrupted in order to let you fix the conflicts. Just follow the instructions and re-run the exact same command to resume the process.
Troubleshoots🔗
Nothing to commit🔗
This error typically means everything was already merged into the targeted branch:
Your branch is up to date with 'origin/XXX'
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
Just remove the .commit
and .notes
files and go back to work!