···11+---
22+title: Recommended Git Config
33+date: 2026-02-27
44+description: There are some quality of life configurations for git that can improve your workflow significantly.
55+tags:
66+ - Education
77+authors:
88+ - trueberryless
99+cover:
1010+ alt: A monochrome image of a dark room, featuring deep shadows and minimal light with abstract circles and shapes.
1111+ image: ../../../../public/blog/recommended-git-config.jpg
1212+giscus: true
1313+---
1414+1515+import { Tabs, TabItem } from '@astrojs/starlight/components';
1616+1717+In order to optimize my git workflow, specifically for GitHub, I present you with some configs and tricks that I set up.
1818+1919+## Automatic rebase
2020+2121+Since I like to keep my commit history linear, I personally prefer to rebase instead of merge when I pull new changes from the remote repository. This means that if I run `git pull`, it will not perform a `fetch` and `merge` but rather a `fetch` followed by a `rebase`, which results in my local commits being automatically included on top of the remote commits coming in. That way, I avoid having merge commits that would IMHO pollute the history.
2222+2323+If you want to try this out yourself, use the `--rebase` parameter on `pull` like that:
2424+2525+```bash
2626+git pull --rebase
2727+```
2828+2929+If you feel happy with this workflow, you can set it in your global config, so you don't need to include the `--rebase` option anymore:
3030+3131+```bash
3232+git config --global pull.rebase true
3333+```
3434+3535+## Default branch: `main`
3636+3737+By default, git often initializes new repositories with `master` as the primary branch. However, most modern platforms (especially GitHub) have moved towards using `main`. Instead of renaming your branch every time you run `git init`, you can tell git to use `main` globally by default:
3838+3939+```bash
4040+git config --global init.defaultBranch main
4141+```
4242+4343+## Adding co-authors
4444+4545+I really like to credit people who contributed in any way to my commits. What I find annoying, however, is that you have to know the GitHub email address of the user you want to [Co-author](https://docs.github.com/en/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/creating-a-commit-with-multiple-authors). I used to go to the people's profile, search for a recent commit they made and appending `.patch` to the GitHub commit URL. In the diff that you get this way, you can manually extract the email of the user. But why should I manually do this 1min work if I could spend 10h automating it?
4646+4747+<div style="display: flex; justify-content: space-evenly; align-items: flex-start; gap: 2rem;">
4848+ <img src="https://imgs.xkcd.com/comics/automation.png" alt="An xkcd comic strip titled 'Automation' exploring the discrepancy between theoretical expectation and reality. In the 'THEORY' panel, a graph shows a brief spike for 'WRITING CODE' before a sharp decline as 'AUTOMATION TAKES OVER,' leaving vast 'FREE TIME.' In the 'REALITY' panel, the 'WRITING CODE' spike leads into a fluctuating line of 'DEBUGGING' and 'RETHINKING' that eventually climbs steadily upward as 'ONGOING DEVELOPMENT,' leaving 'NO TIME FOR ORIGINAL TASK ANYMORE' as the workload permanently increases beyond the original baseline." />
4949+ <img src="https://imgs.xkcd.com/comics/is_it_worth_the_time.png" alt="An xkcd comic titled 'Is It Worth the Time?' featuring a grid that calculates the time-saving break-even point over five years. The horizontal axis lists task frequency (50/day to yearly) and the vertical axis lists time saved per task (1 second to 1 day). Each cell shows the maximum time you should spend automating; for instance, saving 30 seconds on a daily task justifies 12 hours of work, while saving 1 second on a yearly task justifies only 5 seconds. The table uses various units like minutes, hours, days, weeks, and months to illustrate the limits of efficient automation." />
5050+</div>
5151+5252+Sorry, I just had to include those two [legendary](https://xkcd.com/1319/) [xkcds](https://xkcd.com/1205/) in here.
5353+5454+---
5555+5656+So I created a little bash script which simplifies adding Co-authors to your commits. All you need is `gh` and `jq` installed, and the little bash script below.
5757+5858+<Tabs>
5959+ <TabItem label="MacOS">
6060+6161+ ```bash
6262+ brew install gh jq
6363+ ```
6464+6565+ </TabItem>
6666+ <TabItem label="Linux">
6767+6868+ ```bash
6969+ sudo apt install gh jq
7070+ ```
7171+7272+ </TabItem>
7373+ <TabItem label="Windows">
7474+7575+ :::note
7676+ Just use WSL please.
7777+ :::
7878+7979+ </TabItem>
8080+</Tabs>
8181+8282+Save this bash script as `git-ucommit` to a folder that is in your `$PATH` (like `~/bin` or `/usr/local/bin`) and make it executable with `chmod +x ~/bin/git-ucommit`:
8383+8484+```bash
8585+// ~/bin/git-ucommit
8686+#!/usr/bin/env bash
8787+8888+# Check for dependencies
8989+if ! command -v gh &> /dev/null || ! command -v jq &> /dev/null; then
9090+ echo "Error: 'gh' (GitHub CLI) and 'jq' are required."
9191+ exit 1
9292+fi
9393+9494+args=()
9595+usernames=()
9696+message=""
9797+9898+# Parse arguments
9999+while [[ $# -gt 0 ]]; do
100100+ case "$1" in
101101+ -u|--user)
102102+ usernames+=("$2")
103103+ shift 2
104104+ ;;
105105+ -m|--message)
106106+ message="$2"
107107+ shift 2
108108+ ;;
109109+ *)
110110+ args+=("$1")
111111+ shift
112112+ ;;
113113+ esac
114114+done
115115+116116+trailer_args=()
117117+118118+# Resolve GitHub usernames to Co-authored-by trailers
119119+for user in "${usernames[@]}"; do
120120+ user_json=$(gh api users/"$user" 2>/dev/null)
121121+ if [[ $? -ne 0 ]]; then
122122+ echo "Warning: Could not find GitHub user '$user'. Skipping."
123123+ continue
124124+ fi
125125+126126+ name=$(echo "$user_json" | jq -r '.name // .login')
127127+ id=$(echo "$user_json" | jq -r '.id')
128128+ email="$id+$user@users.noreply.github.com"
129129+130130+ trailer_args+=(--trailer "Co-authored-by: $name <$email>")
131131+done
132132+133133+# Execute the commit
134134+if [[ -n "$message" ]]; then
135135+ final_msg=$(echo -e "$message" | git interpret-trailers "${trailer_args[@]}")
136136+ git commit "${args[@]}" -m "$final_msg"
137137+else
138138+ # No -m flag? Inject trailers and open the editor
139139+ git commit "${args[@]}" "${trailer_args[@]}" -e
140140+fi
141141+```
142142+143143+Since the file name starts with `git-`, you do not even need to create a git alias, as it is smart enough to detect your executable and just allows you run:
144144+145145+```bash
146146+git ucommit -m "fix: suggestions" -u trueberryless -u delucis
147147+```
148148+149149+:::note
150150+Unfortunately, I didn't find a way to add those options to the default `commit` command, so I prepended the letter `u` to it, which stands for users.
151151+:::
152152+153153+I myself integrated this functionality into my [nix-darwin](https://github.com/nix-darwin/nix-darwin) setup. Check out my [Nix module](https://github.com/trueberryless/nix/blob/a1be76b4723b0061c34cca1063a477774156ce0a/modules/git-tools.nix) if you can profit from this setup.
154154+155155+## Summary
156156+157157+**🔄 Automatic Rebase on Pull**
158158+> `git config --global pull.rebase true`
159159+>
160160+> Sets your global configuration to perform a rebase instead of a merge when pulling. This keeps your git history linear and avoids unnecessary merge commits.
161161+162162+**🌱 Modern Default Branch**
163163+> `git config --global init.defaultBranch main`
164164+>
165165+> Ensures every new local repository you initialize starts with `main` instead of `master`, aligning your local environment with GitHub's defaults.
166166+167167+**👥 Simplified Co-Authoring**
168168+> `git ucommit -m "message" -u <username>`
169169+>
170170+> Uses a custom bash script alongside `gh` and `jq` to automatically resolve GitHub usernames to the correct "Co-authored-by" trailers, saving you from manual email lookups.
171171+172172+## Resources
173173+174174+Here are some helpful resources for optimizing your Git and GitHub workflow:
175175+176176+- [GitHub CLI (gh) Documentation](https://cli.github.com/manual/)
177177+- [Creating a commit with multiple authors](https://docs.github.com/en/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/creating-a-commit-with-multiple-authors)
178178+- [Git Interpret Trailers Documentation](https://git-scm.com/docs/git-interpret-trailers)
179179+180180+That's it! With these tweaks, your local environment stays modern, your history stays clean, and giving credit to your collaborators becomes a breeze. Happy coding!
+9
src/content/docs/credits.mdx
···63636464<ImageCreditsSection>
6565 <ImageCredit
6666+ image="/public/blog/recommended-git-config.jpg"
6767+ title="A Black Background With Lots of Circles and Bubbles"
6868+ author="Aedrian Salazar"
6969+ authorUrl="https://unsplash.com/@aedrian"
7070+ sourceUrl="https://unsplash.com/photos/a-black-background-with-lots-of-circles-and-bubbles-HBD5k7sA3MQ"
7171+ usedOn="Recommended Git Config"
7272+ usedOnUrl="/blog/recommended-git-config"
7373+ />
7474+ <ImageCredit
6675 image="/public/blog/authors/artificial-intelligence.jpg"
6776 title="A Brain Displayed with Glowing Blue Lines"
6877 author="Shubham Dhage"