Skip to content
← Back to blog
5 min read

Save-Work: one command, four Git steps, and three ways I almost leaked your password

  • powershell
  • git
  • opensource
  • security

I built GitEasy because I watched too many people close their terminal rather than remember git add --all && git commit -m "..." && git pull --rebase && git push. Four commands. Every time. One forgotten flag and the pull overwrites your work. That's not a workflow — it's a quiz with consequences.

The result is a single PowerShell command called Save-Work. You run it; it stages your changes, commits them, pulls any updates from the remote, and pushes — in that order, every time. If something breaks, it tells you in plain English and writes a log.

Simple enough. But building it taught me more about credential leaks in Git tooling than I expected.

What Save-Work actually does

Save-Work -Message "Fix the date formatting bug"

That one line runs four Git steps, in order:

  1. git add --all — stages every changed file
  2. git commit -m "Fix the date formatting bug" — commits with your message
  3. git pull --rebase — pulls remote changes (rebase keeps history cleaner than merge)
  4. git push — pushes to origin

Not ready to push yet?

Save-Work -Message "WIP: refactoring the parser" -NoPush

Need to bump the version in your module manifest at the same time?

Save-Work -Message "Add validation to date parser" -BumpVersion -BumpKind Minor

This is the whole pitch. You stop memorizing commands and start describing what you did.

The safety checks that run before anything happens

Before any of those four Git steps fire, Save-Work runs a sequence of checks:

  • Are you inside a Git repository? If not, it stops immediately and tells you.
  • Is a merge or rebase in progress? Committing mid-merge isn't saving your work — it's recording a mess. GitEasy refuses.
  • Is your commit message too short or blank? It validates the message and rejects empty strings. A commit you can't read six months later isn't useful.
  • Is there a credential embedded in your remote URL? This one surprised me when I first caught it.

That last check exists because of something I found during testing. It's common for developers to embed a personal access token directly in their remote URL — something like https://mytoken@github.com/user/repo.git. When Git operations fail, error messages often include the full URL. If that URL has your token in it, and GitEasy is writing error output to a log file, your secret just landed on disk in plain text.

Set-Token, the command for configuring your remote, refuses to accept embedded credentials in the URL at all. And Save-Work, on every run, checks the configured remote before doing anything and warns you if a credential pattern is detected.

Why routing through one private function matters

Every single Git call in GitEasy — across all 21 commands — goes through one private function: Invoke-GEGit. Not as an architectural nicety. As a security chokepoint.

This is where credential scrubbing happens. Every error message that comes back from Git gets cleaned before it touches a log file. This is also where the structured log entries get written, where exit codes get normalized, and where Git output gets translated from raw strings into PowerShell objects that other commands can work with.

When I ran a security review on the module, I found three places where the scrubbing wasn't happening: a verbose log write, an error fallback path, and a URL-validation failure message. All three were leaking the raw Git output — which, in certain edge cases, could include a credential. All three were fixed by routing through the existing scrubber. The pattern already existed; I just had gaps in coverage.

One function to audit. One place to fix. That's the practical argument for the design.

The log lifecycle you don't have to manage

GitEasy writes a per-invocation log file for every command, silently, in the background. If the operation succeeds, you never see it. If something fails, Show-Diagnostic opens or lists recent logs, so you can see exactly what Git said — after scrubbing.

Logs older than 30 days are pruned automatically the next time you use GitEasy. You never need to manage the folder.

Show-Diagnostic -List   # show recent log files
Show-Diagnostic -All    # open the log folder in Explorer

This matters for the audience GitEasy is built for: people who need version control but don't want to babysit a tooling infrastructure. The logs are there when things go wrong. They disappear when they're not needed.

What GitEasy won't do — and why that's on purpose

If you want to rebase interactively, squash commits, amend history, manage submodules, or work with Git LFS — GitEasy won't help you. These aren't features I forgot to add.

Interactive rebase requires understanding what you're reshaping. Squash is a judgment call about which commits belong together. Amending published history breaks anyone else who's pulled that branch. These operations carry real risk when wrapped in automation, and the risk is higher than the cost of typing the raw Git commands yourself.

GitEasy is for the person who needs version control for their scripts, their writing, their configuration files — not the engineer squashing feature branches before a PR review. If git rebase -i HEAD~10 is in your daily rotation, GitEasy is probably in your way.

Installing it

GitEasy is on PSGallery now, version 1.5.5:

Install-Module GitEasy

To verify your credentials are wired up correctly:

Test-Login

Green means Save-Work will work. Red tells you exactly what needs fixing.

The module is MPL 2.0 licensed — you can fork it, use it in your own tools, modify it. The only constraint is that you can't relicense the GitEasy source itself.


The design question I keep thinking about: does plain-English naming (Save-Work, Find-CodeChange, Show-History) actually help non-developers, or does the unfamiliarity with PowerShell verb patterns cancel out the plain-English gain? If you've tried GitEasy — or decided not to — I'm genuinely curious what the naming did for you.