-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 021b5ba
Showing
3 changed files
with
497 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2024 sideshowbarker | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,286 @@ | ||
## git-gloss ✨ makes git logs show PR/issue/review links | ||
|
||
`git-gloss` automatically adds [git notes](https://scottchacon.com/2010/08/25/notes/) to all your git logs — with GitHub PR/issue/reviewer/author links. | ||
|
||
--- | ||
|
||
### How to use git-gloss | ||
|
||
You can download and run `git-gloss` within a directory having a GitHub repo clone by just doing this: | ||
|
||
``` | ||
curl -fsSLO https://sideshowbarker.github.io/git-gloss/git-gloss && bash ./git-gloss | ||
``` | ||
|
||
That will add [git notes](https://scottchacon.com/2010/08/25/notes/) locally for all commits in the local commit history with an associated GitHub pull request. | ||
|
||
Then, when you run `git log`, the log output for each commit will look something like this: | ||
|
||
``` | ||
commit 9812031a02e539f08a6936e9c17d919a44c912b8 | ||
Author: Jonatan Klemets | ||
Date: Sun Jul 23 19:38:04 2023 +0300 | ||
LibWeb: Implement spec-compliant integer parsing | ||
This patch adds two new methods named `parse_non_negative_integer` and | ||
`parse_integer` inside the `Web::HTML` namespace that uses `StringUtils` | ||
under the hood but adds a bit more logic to make it spec compliant. | ||
Notes: | ||
Author: https://github.com/Jon4t4n 🔰 | ||
Commit: https://github.com/SerenityOS/serenity/commit/9812031a02 | ||
Pull-request: https://github.com/SerenityOS/serenity/pull/20140 | ||
Issue: https://github.com/SerenityOS/serenity/issues/19937 | ||
Reviewed-by: https://github.com/AtkinsSJ ✅ | ||
Reviewed-by: https://github.com/nico | ||
``` | ||
|
||
🔰 – indicates this is author’s first commit to the repo\ | ||
✅ – indicates a review approval | ||
|
||
--- | ||
|
||
> [!TIP] | ||
> If you want to put notes in the logs for multiple repos, see the [Add a “git gloss” command](#add-a-git-gloss-command) section for a how-to on setting up a new `git gloss` command that you can run just as you would any other `git` command. | ||
--- | ||
|
||
### How to share the notes | ||
|
||
Once `git-gloss` finishes running, here’s how you can share the notes with everyone in your GitHub project: | ||
|
||
1. Push the notes back to your project remote at GitHub by running this command: | ||
|
||
``` | ||
git push origin 'refs/notes/*' | ||
``` | ||
|
||
2. Others in your project can then fetch the notes from GitHub by running this command: | ||
|
||
``` | ||
git fetch origin 'refs/notes/*:refs/notes/*' | ||
``` | ||
|
||
Alternatively, rather than running the above command manually, others in the project can update their git configuration by running the following command; | ||
|
||
``` | ||
git config --add remote.origin.fetch '+refs/notes/*:refs/notes/*' | ||
``` | ||
|
||
That will cause all notes to be fetched from the remote every time they use `git fetch` or `git pull`. | ||
|
||
3. Run `git-gloss` again to add notes for any new commits made after the last time you ran `git-gloss`. | ||
|
||
4. Keep your project’s notes up to date by repeating steps 1 to 3 at a regular cadence (e.g., once day or so). | ||
|
||
--- | ||
|
||
### How long does it take? | ||
|
||
`git-gloss` can process at most about 1000 commits per hour — about 17 or 18 commits per minute. | ||
|
||
So, the first time you run it in a repo with many commits, it’ll take a long time — hours, or even a day or more. | ||
|
||
For example, if your repo has somewhere around 1000 commits, it’ll take at least 1 hour to finish. If your repo has somewhere around 10,000 commits, it’ll take more than 10 hours. And so on. | ||
|
||
> [!NOTE] | ||
> You can stop `git-gloss` at any time with <kbd>Ctrl</kbd>-<kbd>C</kbd>. After stopping it, when you run it again, it will start off wherever it left off. So, if you have a repo with somewhere around 2000 commits, and you stopped `git-gloss` after it was running for about an hour, then it will run for about another hour before it finishes. | ||
### How to “back up” notes | ||
|
||
Given how long (multiple hours) it can take `git-gloss` to add all notes for a large history, you should do this: | ||
|
||
1. Periodically stop `git-gloss` (say, once an hour), using <kbd>Ctrl</kbd>-<kbd>C</kbd>. | ||
|
||
2. Run the following command to push your (partial) notes to your project repo: | ||
|
||
``` | ||
git push origin 'refs/notes/*' | ||
``` | ||
|
||
3. Restart `git-gloss`, to continue adding more notes. | ||
|
||
4. Repeat steps 1 to 3 periodically (say, once an hour) until `git-gloss` finishes. | ||
|
||
> [!IMPORTANT] | ||
> Doing the steps above will ensure that you have a “backup” of the notes you’ve generated so far — and if ever needed, you can then “restore” your notes from that backup by running the following command: | ||
> | ||
> ``` | ||
> git fetch origin 'refs/notes/*:refs/notes/*' | ||
> ``` | ||
### Why is it so slow? | ||
For each commit `git-gloss` processes, it makes 4 calls to GitHub API endpoints — requiring network resources and time. And in a typical environment, for each commit the total time required (mostly due to those calls) happens to work out to around 3.5 seconds or so — which means it can process only about 17 or 18 commits per minute. | ||
Regardless, the GitHub API has [rate limits](https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api) that prevent making more than 5000 requests per hour — which works out to about 83 requests per minute. And so, because `git-gloss` makes 4 requests for each commit, that also limits it to being able to make only enough requests per minute for 20 to 21 commits at most (20 X 4 X 60 = 4800). | ||
> [!TIP] | ||
> If you have a connection with very high bandwidth, it’s imaginable that `git-gloss` might end up taking less than 3 seconds for each commit — which means it might exceed that 5000-requests-per-hour rate limit. | ||
> | ||
> If you do exceed the limit, set the [`GH_THROTTLE`](#gh_throttle) environment variable to a high-enough value to prevent that. | ||
### How to avoid 403s | ||
You must have the [`GH_TOKEN` or `GITHUB_TOKEN`](https://cli.github.com/manual/gh_help_environment) environment variables set in your environment in order to use `git-gloss` — with the values set to a [GitHub authentication token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens). Otherwise, `git-gloss` will fail with 403 errors less than a minute after you start it — after processing only 15 or so commits. | ||
If you *do* already have the `GH_TOKEN` or `GITHUB_TOKEN` environment variables set, and `git-gloss` is failing with 403 errors — then you’ll need to set [`GH_THROTTLE`](#gh_throttle) to a high-enough value to avoid exceeding GitHub’s [rate limits](https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api). | ||
### How to fix errors | ||
`git-gloss` doesn’t yet have error handling for the case where a call to the GitHub API fails. So you can keep a log of its output, and review it after `git-gloss` finishes. You can create a log by invoking `git-gloss` like this: | ||
``` | ||
git-gloss 2>&1 | tee $(mktemp -p .) | ||
``` | ||
That creates a log file in the current directory with a name such as `tmp.gndYHHPKgA` — using the `mktemp` and `tee` utilities, which are standard in any Linux/Unix environment (including the macOS Terminal/shell environment). | ||
After `git-log` finishes (or even as it’s running), you can review the log for error output that looks like this: | ||
``` | ||
1320/56162 67c727177e https://github.com/LadybirdBrowser/ladybird/commit/67c727177e | ||
jq: parse error: Invalid numeric literal at line 1, column 314 | ||
jq: parse error: Invalid numeric literal at line 1, column 314 | ||
jq: error (at <stdin>:1): Cannot index object with number | ||
jq: parse error: Invalid numeric literal at line 1, column 315 | ||
``` | ||
For each case like that which you see in the log output, you’ll need to complete the following steps: | ||
1. Remove any note which `git-gloss` may have added for the given commit: | ||
``` | ||
git notes remove 67c727177e | ||
``` | ||
2. (Re)add a note for the given commit, by running `git-gloss` with the commit hash specified: | ||
``` | ||
git-gloss 67c727177e | ||
``` | ||
> [!CAUTION] | ||
> `git-gloss` provides no way to undo its actions and remove all notes it added. The only practical way to undo its actions may be to completely remove all notes, including any notes you may have added by other means. | ||
> | ||
> But if you haven’t added notes by any other means: To remove all `git-gloss`-added notes, run this: | ||
> | ||
> ``` | ||
> git update-ref -d refs/notes/commits | ||
> ``` | ||
### Other problems | ||
``` | ||
Auto packing the repository in background for optimum performance. | ||
See "git help gc" for manual housekeeping. | ||
warning: The last gc run reported the following. Please correct the root cause | ||
and remove .git/gc.log | ||
Automatic cleanup will not be performed until the file is removed. | ||
|
||
warning: There are too many unreachable loose objects; run 'git prune' to remove them. | ||
``` | ||
Already up to date. | ||
### Dependencies | ||
* `git` – any version ([v2.42+](https://stackoverflow.com/a/76633969/)) with support for the `--no-separator` option for the `git notes` command | ||
* `jq` – [https://jqlang.github.io/jq/](https://jqlang.github.io/jq/) (JSON processor) | ||
* `gh` – [https://cli.github.com/](https://cli.github.com/) (GitHub CLI), with the [`GH_TOKEN` or `GITHUB_TOKEN`](https://cli.github.com/manual/gh_help_environment) environment variables set | ||
* `grep` – any grep-compatible program | ||
> [!IMPORTANT] | ||
> On macOS in particular, a grep-compatible program other than the Apple-provided `grep` — e.g., [ripgrep](https://github.com/BurntSushi/ripgrep#installation) or [GNU grep](https://apple.stackexchange.com/a/193300) — is recommended for performance reasons); example: | ||
> | ||
> ``` | ||
> brew install ripgrep | ||
> brew install grep | ||
> ``` | ||
### Environment variables | ||
You can affect the `git-gloss` behavior using the environment variables described in this section. | ||
> [!TIP] | ||
> Rather than separately exporting each environment variable to your shell, you can instead specify them all at the same time in the invocation you use for running `git-gloss` — like this: | ||
> | ||
> ``` | ||
> OTHER_OTHER_REPO=LadybirdBrowser/ancient-history OTHER_REPO=SerenityOS/serenity \ | ||
> GREP=rg GIT=/opt/homebrew/bin/git ./git-gloss | ||
>``` | ||
#### `GIT` | ||
You can use this to specify a path to a different `git` binary — for instance, in the case where you have multiple different `git` versions on your system; example: | ||
``` | ||
export GIT=/opt/homebrew/bin/git | ||
``` | ||
> [!NOTE] | ||
> Because `git-gloss` calls the `git notes` command with the `--no-separator` option — which was added in git [version 2.42+](https://stackoverflow.com/a/76633969/) — the git version you use with `git-gloss` must be version 2.42 or later. | ||
#### `GREP` | ||
You can use this to specify a path to any grep-compatible binary on your system; for instance, to avoid using the Apple-provided `grep` on macOS; example: | ||
``` | ||
export GREP=/opt/homebrew/bin/rg | ||
``` | ||
> [!IMPORTANT] | ||
> On macOS in particular, a grep-compatible program other than the Apple-provided `grep` — e.g., [ripgrep](https://github.com/BurntSushi/ripgrep#installation) or [GNU grep](https://apple.stackexchange.com/a/193300) — is recommended for performance reasons); example: | ||
> | ||
> ``` | ||
> brew install ripgrep | ||
> brew install grep | ||
> ``` | ||
#### `GH_THROTTLE` | ||
If you’re getting 403 responses from the GitHub API due to exceeding the API’s 5000-requests-per-hour [rate limit](https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api), you can use this to specify a number of seconds (or a fraction of a second) that `git-gloss` will “sleep” between processing each commit (and thus make fewer requests per minute, and fewer requests per hour). | ||
``` | ||
export GH_THROTTLE=1 | ||
``` | ||
#### `OTHER_REPO` | ||
You can use this to specify an `[owner]/[repo]` repo other than the current repo; e.g., a repo the current repo shares part of its commit history with (because the current repo was created from an older repo); example: | ||
``` | ||
export OTHER_REPO=SerenityOS/serenity | ||
``` | ||
If you specify an `OTHER_REPO` value, then if `git-gloss` can’t find any pull request for a particular commit in the current repo, it will then look for a pull request in the repo you specified in the `OTHER_REPO` value. | ||
> [!WARNING] | ||
> Setting an `OTHER_REPO` value causes `git-commit` to process commit histories from multiple repos, and will likely make `git-gloss` take significantly longer to finish (because it causes 2 additional GitHub API calls for each commit — on top of the 4 GitHub API calls that `git-gloss` already makes for each commit). | ||
#### `OTHER_OTHER_REPO` | ||
You can use this in addition to `OTHER_REPO` — if you have a third repo with a shared history; example: | ||
``` | ||
export OTHER_OTHER_REPO=LadybirdBrowser/ancient-history | ||
``` | ||
> [!WARNING] | ||
> Setting an `OTHER_OTHER_REPO` value will likely make `git-gloss` take significantly longer to finish. | ||
### Add a “git gloss” command | ||
Clone the `git-gloss` repo and add its directory to your `$PATH`: | ||
```bash | ||
git clone https://github.com/sideshowbarker/git-gloss.git | ||
cd git-gloss | ||
echo export PATH=\"$PATH:$PWD\" >> ~/.bash_profile | ||
``` | ||
|
||
Now you can just type `git gloss` in any repo/clone directory, to add notes to the logs for that repo. |
Oops, something went wrong.