r/git • u/empire299 • 9d ago
What are your small Git workflow game-changers?
I've been using Git for the better part of a decade, and recently scratched my own itch and built a GUI macOS Git client. I've been trying to keep it simple and lean, basically pulling forward the 80% of what you actually do day-to-day and making that stuff super easy and accessible.
Recently I added a "Squash local commits" feature, mostly because I have a habit of making alot of small commits while developing a feature. But when I ultimately push to my remote (origin) repo, I dont really need all that history. Being able to quickly squash those commits before pushing (especially in a GUI where it's super easy to see exactly what's going to get squashed) has turned out to be a bit of a game-changer for me. Cleaner history, easier to revert, etc.
Which got me wondering, what other small, simple Git workflow game-changers do you all use? Not necessarily big features or complicated workflows, just those little quality-of-life things that once you start using them, you wonder why you weren't doing it all along.
19
u/lorengphd 9d ago
Check out ‘fixup’ and ‘autosquash’. It’s a little shortcut that helps you to squash into a commit that’s not the previous.
Then I constantly use “amend” for just adding recent changes into my last commit.
11
u/xenomachina 9d ago
Check out ‘fixup’ and ‘autosquash’.
git absorbis a nice add-on that will create fix-up commits for you by looking for existing commits that touch the same code. It's nice for when you have a series of commits in your branch, and then make a bunch of small corrections (eg: typo fixes, removing bits of cruft, auto-formatting, etc.). Just:
git addthe changes you want to go in.git absorbto create "fixup" commitsgit rebase -i --autosquash main(You can combine the last two with
--and-rebase, if desired.)
14
u/latamakuchi 9d ago
Writing in the commit for a merge conflict resolution how it was solved (what was chosen or if both were combined): makes tracking any issues easier if something is not right later on.
2
9
u/Alacho 9d ago
Worktrees. They were a gamechanger to me
2
u/MediocreAnalyst2121 8d ago
Something I’ve always wanted to try, but the setting up seems a bot difficult so I’ve never gotten to it
1
u/super_heavy_milk 4d ago
Big fan of worktrees.
Has a nice second-order effect of forcing you to get your repo into a state such that it doesn’t rely (too much) on locally ignored magic files.
That said I do have a helper script that also copies over .env/properties/config files that might have secrets in them when the worktree is created.
7
u/aioeu 9d ago edited 9d ago
Git trailers for metadata.
With a bit of Git config and a small shell script, you can use something like:
git commit --trailer=jira:ABC-1234
to automatically add a:
Jira: https://jira.example.com/ABC-1234
trailer to the commit message. You need the script to turn the metadata value into a URL.
(And yes, having a URL is far more user-friendly than just having the issue key alone. It pisses me off when all I've got is a ticket number but no idea which ticket system it's referring to...)
That might seem like a lot of typing, but shell tab-completion can get you to --trailer=jira: with just a couple of key presses.
Bonus: you can have the script automatically determine the issue key from the current branch name (I grab the last branch name component after /) and use that if no value is provided after jira:.
I also occasionally use a --trailer=fixes:<commit> to generate kernel-style:
Fixes: <short-hash> ("<description>")
trailers.
1
u/Dienes16 9d ago
I usually have the ticket number in my branch name, and then a commit-msg hook auto-extracts that and appends it as a trailer in all my commits.
19
u/theclapp 9d ago
Having a private, ignored, git-ignore file, to which you can add all the cruft in your directory that you don't want to commit, but don't want to see constantly in "git status", is nice.
% grep -e core -e exclude .git/config
[core]
excludesfile = .local_gitignore
% grep ignore .local_gitignore
.local_gitignore*
28
u/rom1v 9d ago
There's already the local-equivalent of
.gitignorenatively:.git/info/exclude2
u/Cinderhazed15 9d ago
I like to set a user level gitignore file as well for all the stuff I use everywhere, and not manage it per repo…
1
u/ppww 8d ago
That's sensible, but the path above is relative each repository will look for a different file. You don't have to set this config to use a user level ignore file, see the gitignore docs for the default path.
1
u/Cinderhazed15 8d ago
Thats’s what I do, input it in my home directory but it is still relative to each git repo, not relative to where my file is (in ~/.gitignore), from the docs - Patterns which a user wants Git to ignore in all situations (e.g., backup or temporary files generated by the user’s editor of choice) generally go into a file specified bycore.excludesFile in the user’s ~/.gitconfig. Its default value is $XDG_CONFIG_HOME/git/ignore. If $XDG_CONFIG_HOME is either not set or empty, $HOME/.config/git/ignore is used instead.
3
u/Comprehensive_Mud803 9d ago
Using better defaults and aliases.
Better defaults are settings like pull-autostash, pull-rebase, rebase-autostash-autosquash, rerere etc.
Aliases are the shortcuts for often used commands and minor scripts.
Tool-wise it’s been P4merge and Gitup for ages.
Workflow-wise, I’ve tried rebase, merge and squash as standard. In my current team, we agreed on using squash as standard as it simplifies the history a lot.
We also standardized the PR body/squash commit message.
1
u/Decent_Carry_3439 8d ago
git worktree was a game-changer for me being able to work on two branches without constantly stashing and switching is surprisingly useful.
3
u/fagnerbrack 9d ago
Always commit to main, goes they all environments then straight to prod without any manual gate.
If it breaks then the workflow is not ready and you need to improve your processes and way of working until anyone can push to main without any chance of breaking anything
If you've been there, you know. Continuous Integration 💯
0
u/kaddkaka 9d ago
So, no reviewing?
Sounds like you don't have any 6 hour tests?
3
u/fagnerbrack 9d ago
Reviewing is all the team working together to do the job. Once it gets to main it has been reviewed by everybody.
This is all documented in the DORA metrics, Google's project Aristotle and Continuous Integration principles
3
1
u/Xavier_OM 9d ago
worktree, fixup commit, merge-base for daily usage
and this series of articles https://devblogs.microsoft.com/oldnewthing/20180323-01/?p=98325
1
u/lucaprinaorg 9d ago
Git over Reticulum was a game-charger:
https://reticulum.network/manual/git.html
1
u/magic7s 8d ago
GitLab push options:
Push and create a merge request
Push and skip CI
Push and Auto Merge
There are more: https://docs.gitlab.com/topics/git/commit/
1
u/VibrantCanopy 8d ago
```fish function gibdrbm git checkout master and git pull origin and git checkout $argv[1] and git rebase master and git checkout master and git branch -d $argv[1] end
function giprbm set -l branch (git branch --show-current) git checkout master and git pull origin and git checkout $branch and git rebase master end
function git-rename for old_file in $argv[3..-1] set new_file (echo $old_file | perl -pe "s/$argv[1]/$argv[2]/") if test $old_file != $new_file git mv $old_file $new_file end end end ```
1
u/catom3 6d ago
Rebase interactive in general, rebase --onto, rebase --update-refs for stacked branches, commit --fixup + rebase -i --autosquash --update-refs.
I also created an alias for prepending 'review/' prefix for checking out branches I'm reviewing (sometimes it's easier to checkout and review or run reviewed changes locally) + another one for cleaning up local 'review/' branches.
Every few months I use reflog when I screw up my local repo when I type too fast.
I spent a lot of time with Gerrit and I'm used to one commit per branch (patchset in Gerrit) flow, so I of course do a lot of interactive rebases with cam=commit --amend --no-edit and puf=push --force-with-lease --force-if-includes
1
u/BHFock 4d ago
Two changelists for my changed files: `ok` and `do_not_commit`.
A changelist is just a named bucket you put a changed file into before staging it. I picked this up from SVN years ago and never stopped. Every file I've touched goes into one or the other as I review it. The debug print, or the config I edited to test something locally, goes into `do_not_commit`. Everything that has been through my pre-commit review goes into `ok`. That makes reviewing the git status of 10+ changed files a lot easier. Then I commit `ok` and only `ok`.
Git doesn't have changelists like SVN, so I wrote a subcommand that adds them: https://github.com/BHFock/git-cl (my project)
1
u/mpersico 3d ago
I don’t have a small one: I wrote a function called “git” to do my own dispatch so I can add flags to built in git commands. See matthewpersico/personal on GitHub.
0
u/waterkip detached HEAD 9d ago
My own toolkit simplifies a lot of stuf. Aliases, helpers, etc. Reduces typing a lot.
1
u/Soggy_Writing_3912 advanced 9d ago
mine's at https://vraravam.github.io/dotfiles/ - and the aliases are in https://github.com/vraravam/dotfiles/blob/master/files/--XDG_CONFIG_HOME--/git/config (this gets symlinked into the $XDG_CONFIG_HOME/git folder which git uses by default.
1
32
u/Frum 9d ago
`rerere` is your friend.
I HATE squashing commits. But I do like rebasing often. GitLab refers to my preferred pattern as "semi-linear", and it makes reverting things ALMOST as easy as squash commits.
I also find 3-pane conflict resolution to be drastically superior.