惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

SecWiki News
SecWiki News
量子位
The Cloudflare Blog
美团技术团队
T
The Exploit Database - CXSecurity.com
博客园 - 【当耐特】
Spread Privacy
Spread Privacy
P
Proofpoint News Feed
C
CXSECURITY Database RSS Feed - CXSecurity.com
博客园 - 三生石上(FineUI控件)
T
Tor Project blog
博客园 - 司徒正美
宝玉的分享
宝玉的分享
T
Threatpost
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
S
Secure Thoughts
T
Threat Research - Cisco Blogs
Hacker News: Ask HN
Hacker News: Ask HN
Jina AI
Jina AI
博客园 - 聂微东
A
Arctic Wolf
I
Intezer
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Know Your Adversary
Know Your Adversary
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
爱范儿
爱范儿
Hugging Face - Blog
Hugging Face - Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
小众软件
小众软件
T
Tailwind CSS Blog
The Hacker News
The Hacker News
L
LINUX DO - 最新话题
Hacker News - Newest:
Hacker News - Newest: "LLM"
WordPress大学
WordPress大学
S
SegmentFault 最新的问题
TaoSecurity Blog
TaoSecurity Blog
Project Zero
Project Zero
博客园 - 叶小钗
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Cloudbric
Cloudbric
雷峰网
雷峰网
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
大猫的无限游戏
大猫的无限游戏
D
Darknet – Hacking Tools, Hacker News & Cyber Security
T
Troy Hunt's Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
V2EX - 技术
V2EX - 技术
The GitHub Blog
The GitHub Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
P
Privacy & Cybersecurity Law Blog

Butler's Log

Agentic Version Control Benchmarks Grit: rewriting Git in Rust with agents Git Merge 2026 Agent-safe Git with GitButler We’ve raised $17M to build what comes after Git Announcing the GitButler CLI for Linux The Great CSS Expansion A couple of git nits Simplifying Git by Using GitButler Introducing the GitButler CLI GitButler 0.19 - "Commander Keen" But Head: Crafting a Custom Font MCP vs RAG: Two Very Different Ways to Gain Context Getting Started With GitButler Agents Using the GitButler MCP Server to Build Better AI-Driven Git Workflows Using GitButler With Multiple GitHub Accounts Advent of Code! Upcoming GitButler Events Use GitButler for your Gerrit workflow Integrating GitButler and GitHub Enterprise Butler Flow: shipping code faster (but less like Alfred, more like CI on steroids) - Part 3 Butler Flow: shipping code faster (but less like Alfred, more like CI on steroids) - Part 2 Butler Flow: shipping code faster (but less like Alfred, more like CI on steroids) - Part 1 Grid Happens: Because Flexbox Wasn’t Enough Using Cursor Hooks for automatic version control Deep Dive into the new Cursor Hooks A Responsive Item Counter with CSS only GitButler 0.16 - "Sweet Sixteen" GitButler's Claude Code tab GitButler's Annual Open Source Pledge Report Git Mini Summit 2025 Videos Automate Your AI Workflows with Claude Code Hooks Managing Multiple Claude Code Sessions Without Worktrees GitButler 0.15 - "Quirky Quinceañera" 20 years of Git. Still weird, still wonderful. GitButler's new patch based Code Review (Beta) Going down the rabbit hole of Git's new bundle-uri How to do patch-based review with git range-diff How Core Git Developers Configure Git Why is Git Autocorrect too fast for Formula One drivers? Stacked Branches with GitButler Git Merge 2024 Talks are Up GitButler 0.13 - "Lucky Baseball" Fearless Rebasing Git Merge 2024 Why GitHub Actually Won GitButler is joining the Open Source Pledge The New Era of Town Hall Chat The Future of Open Source GitButler is now Fair Source Git Merge 2024 GitButler 0.12 - "Stingy Baker" The Birth of THE MERGE GitButler for Windows Fixing up Git with Autosquash The Git Zeitgeist Git Worktrees and GitButler DevWorld Git Slides Git Tips and Tricks Git Tips 1: Oldies but Goodies Git Tips 3: Really Large Repositories FOSDEM Git Talk Opening Up GitButler Debugging Tauri in VS Code Advent of GitButler Code Signing Commits in Git, Explained Virtual Branches Alpha Our We Are Developers Adventure Building Virtual Branches DevDays in Vilnius The Future of Software and Open Source Introducing GitButler
Git Tips 2: New Stuff in Git
Scott Chacon · 2024-02-08 · via Butler's Log

Next up in our 3 part series on "Stuff you may not know about Git", we have New Stuff!

Here I'm going to cover 5 relatively new things in Git that you may not have heard about, because why would you?

We'll cover:

  • Git Branch Stuff
  • Safe Force Pushing
  • SSH Commit Signing
  • Push Signing
  • Git Maintenance

Let's dig in!

This is pretty minor, but one thing that's always bugged me about Git is that I run git branch a lot to view what branches I have, but they're in the dumbest possible order (alphabetic) and there are a million of them after a while.

At some point I started naming my branches in a way to partially cope with this. Every branch would be something like sc-0831-my-thing meaning that the branch topic was "my thing", it was created on August 31st and the sc are my initials so I can group them by whose branch. It's a lot of stupid metadata to try to cram into a branch name just because of how it's listed.

However, now we can ask Git to do two things that help with this. We can ask it to sort by objectsizeauthordatecommitterdatecreatordate, or taggerdate with the --sort option and we can set it as a default with the branch.sort config setting.

So for example, if I want to sort by last commit date descending, I can run:

$ git config --global branch.sort -committerdate

And now the default will show the branch that I last committed to at the top.

💡

Important note: the -committerdate has a leading - but not a double dash. It's just a negative. I've seen people mess this up and then things break.

However, now if I have a bunch of branches, that will scroll off the screen. Sad. But now Git also has a way to take a list of branches and try to split it into columns to make better use of the screen real estate. You can do this either with the new --column option, or with the column.ui setting.

Check it out:

Nice sorted columns for my branch output

As another sort of funny thing, in order to help with this, Git implemented it's own list to column terminal command that is sort of completely independent of anything else in Git and is it's own command called git column.

Just in case there is anything else you need to convert into columns that isn't Git related.

The next interesting thing that Git has added somewhat recently is a way to do much safer forced pushes.

Generally most of us don't love doing forced pushes, because there is always a chance that you're overwriting someone else's commits. Let's take a scenario:

  • You commit and push something to GitHub
  • Someone else pulls it down, commits something and pushes it back up.
  • You amend a commit, rewriting the history, and force push it, not knowing that anyone had based something off your work.
  • This effectively removes what the other person had done.

What you really want to do is check to see if anyone else had pushed and only force push if the answer is no. However, there is always a bit of a race condition here because even if you check first, in the second it takes you to then push, something else could have landed from elsewhere in the meantime.

So, Git has created a new force pushing option called --force-with-lease that will essentially check that what you last pushed is still what's on the server before it will force the new branch update.

A failed --force-with-lease push

If someone has updated the remote ref (pushed in the meantime), then push now fails with a "stale info" error.

If you're amending and rebasing stuff a lot, it may be worth setting up a nice little alias for this, because it's almost always better than running --force

$ git config --global alias.fpush push --force-with-lease

May the force be with you.

We wrote about this a few months ago in mind-numbing detail, because the GitButler client does this automatically for you with the flip of a config setting, but if you want to do this on the command line, read on.

Git has supported signing your commits with GPG for a while, but GPG is often pretty difficult to get working properly and completely understand if you've never used it before. Recently, OpenSSH provided a new way to sign data using your existing SSH key and Git has integrated this as an option to use instead of GPG to do the same thing. Also, importantly, GitHub and GitLab support verifying these signatures if you upload your public signing key to your user account there.

It's pretty easy to do. Just set gpg.format to ssh and tell it where your signing key is:

$ git config gpg.format ssh
$ git config user.signingKey ~/.ssh/id_rsa.pub

Now if you run git commit -S it will try to sign your commit with this key. If it succeeds and you upload that public key to GitHub here (under "Signing Keys"), then you'll get pretty "verified" badges on your commits:

Stay vigilant.

I won't go into a ton of detail here because this isn't really widely used, but it might be interesting to some. Git can also now sign pushes, not just commits.

Since none of the major Git hosting solutions (GitHub, GitLab, Bitbucket) support this, it's only really possible to do this if you run your own server. However, if you do, you can run git push --signed in order to sign the ref update on the server and have the server save a transparency log with verifiable signatures somewhere.

If you're interested in this, there is a very nice writeup by Konstantin Ryabitsev over at kernel.org.

Push it real good.

Git Maintenance

The final fun new thing I'll cover is git maintenance.

The maintenance command was introduced in Git 2.30 I believe. It essentially provides a way to add cronjobs that run daily, hourly and weekly maintenance tasks on your Git repositories.

You can turn it on for your Git repository by simply running:

$ git maintenance start

This will modify your .git/config file to add a maintenance.strategy value set to incremental which is a shorthand for the following values:

  • gc: disabled.
  • commit-graph: hourly.
  • prefetch: hourly.
  • loose-objects: daily.
  • incremental-repack: daily.

This means that every hour it will rebuild your commit graph and do a prefetch (we will cover these concepts in the next post), and once per day it will clean up loose objects and put them in pack-files and also repack the object directory using the multi-pack-index feature (read more about that in an incredible blog post from GitHub's Taylor Blau here).

Basically it will just make lots of things faster in the background all the time automatically.

Git maintenance will schedule these cron jobs differently depending on the operating system. On Mac it will add some LaunchAgents like this:

If you're curious what these plist files look like, it's something like this:

You can read more about git maintenance and it's various options here.

OK, now onto our next post where we cover those commit graph and prefetching topics. Let's get into Really Big Repositories.