Git Stash Without the Branch Name

I found a way to stash changes in git without including the branch name in the stash message. This might be a very niche use case but it’s been a minor annoyance for me for some time. If you just want the alias, then add the following to your .gitconfig: [alias] sm = "!f() { git stash || exit 1; rev=$(git rev-parse stash@{0}) && git stash drop stash@{0} || exit 1; git stash store -m \"$1\" $rev; }; f" You can also use this technique for renaming stashes. ...

Stash changes in the index

I just recently discovered that Git 2.35 added the --staged option to the git stash command. This makes it easy to quickly stash only the changes that you’ve staged.

Selectively restoring changes from another branch or commit

Today I learned that you can use the --patch parameter with several git commands. The --patch parameter is probably most known for interactively staging changes from the cli, but I’ve never really used it because I find GUI clients are much more convenient for this. But apparently you can also use it with restore/checkout to grab specific changes from another branch. git restore --source=branch-name --patch This is something I haven’t seen easily done in any git client. ...

Personal git ignore per repository

Today I learned that git has a $GIT_DIR/info/exclude file can contain additional patterns of files to ignore but isn’t committed to the repository. For me this is handy for some tooling configuration files that I use personally but don’t want to clutter the main .gitignore of the repo. If there are some files that you want to always ignore, then you can specify a global ignore file in your git config with core.excludesFile. ...

Edit commit message with git reword

I discovered that a reword option was added to --fixup back in git 2.32 The basic command looks like git commit --fixup=reword:<commit> and you can use it like you would the other autosquash commands. I recommend creating an alias for it though. Thanks to this post, I’ve had a fixup alias that uses fzf to select form recent commits so I created a similar one for reword: [alias] reword = "!git log -n 50 --pretty=format:'%h %s' --no-merges | fzf | cut -c -7 | xargs -o -I{} git commit --fixup=reword:{}" Note, if you’re on Windows, you can install fzf via Chocolatey. And you might also be interested in PSFzf which a Powershell module that wraps fzf. ...

Tips for creating merge commits

I’ve reviewed quite a few pull requests in recent years and I’ve noticed some less-than-ideal practices when it comes to creating merge commits so I thought I’d list some things you can do to make life a little easier for someone reviewing your code. Make the commit message as useful as possible A lot has been written about how to write good commit messages, but I rarely see the advice applied to merge commits. They may not be the most exciting type of commit, but they’re still very important. ...

bash vs sh in git hooks on windows

Today I learned that sh is not the same thing as bash.

Cherry pick a range of commits

I just recently learned that you can actually cherry pick a range of commits instead of just a single commit: git cherry-pick c1..c3 The above is using the two-dot range notation (..). I was a bit surprised by this because I thought that this was the purpose of rebase --onto — to take a series of commits and apply them one at a time on top of some other commit. Turns out that they both essentially do the same thing (for each commit they call merge-base under the hood and apply a 3-way merge though you can also think of rebase as a series of cherry picks) but one can be more convenient than the other depending on what you’re doing or how you prefer to think of the operation. ...

View the conflicts resolved in a merge commit

Today I learned that in Git 2.36, the --remerge-diff option was added to git show. This effectively lets you view any merge conflicts that occurred during a merge commit and how they were resolved. So for instance, git show --remerge-diff <commit-message-id> would show something like: Under the hood, it recreates the merge with the conflicts and diffs it with the merge commit so the conflict markers are shown in red since the merge commit removes the conflict markers during resolution. ...

Git Maintenance

Today I learned about the git maintenance command that runs tasks for regular maintenance of a git repo. If you run git maintenance start in a repo, git will create scheduled tasks to run at regular intervals to perform these tasks in the background like garbage collection. This will optimize and speed up the repo without having to tack them on occasionally as you run other commands. A particularly handy task it will run every hour is prefetch, where it does a git fetch but only pulls down the data and doesn’t update any refs. Then when you actually run git fetch or git pull, it completes almost instantly because it already has all the data. ...