Skip to main content

Rewrite git commit timestamps to fit within or exclude certain time windows

Project description

git-alibi

Rewrite git commit timestamps to fit within (or avoid) configured time windows.

Useful for keeping commit history clean when you work odd hours, across timezones, or want commits to consistently appear within business hours. Alibi saves a backup before every rewrite so changes can always be undone.

Requirements

  • Python 3.11 or newer
  • git 2.25 or newer

Installation

pip (simplest):

cd git-alibi
pip install .

pipx (isolated, recommended for CLI tools):

pipx install /path/to/git-alibi

Virtual environment (if you prefer not to touch system Python):

cd git-alibi
python3 -m venv .venv
source .venv/bin/activate      # Windows: .venv\Scripts\activate
pip install .

Verify the install:

git-alibi --help
# git also picks it up automatically:
git alibi --help

Uninstallation

pip uninstall git-alibi      # if installed with pip
pipx uninstall git-alibi     # if installed with pipx
rm -rf .venv                 # if installed into a venv, just delete it

Quick start

Preview what would change without touching the repo:

git-alibi rewrite --dry-run

Apply the rewrite:

git-alibi rewrite

If the branch was already pushed:

git push --force-with-lease

Undo the last rewrite:

git-alibi restore

Configuration

Alibi is configured with TOML files. Settings in the local file take precedence over the global one.

File Scope
~/.config/alibi/config.toml Global (all repos)
.git/alibi/config.toml Local (this repo only)

Open a config file in $EDITOR (created with commented-out defaults if it doesn't exist):

git-alibi config local
git-alibi config global

Example config

[behavior]
timezone = "America/Chicago"
out_of_window = "nearest"   # nearest / previous / next / random
spacing = "preserve"        # preserve / proportional / even / random

[days]
block = ["SAT", "SUN"]      # never place commits on weekends

[times]
allow = ["09:00-17:00"]     # only allow commits during business hours

[authors]
# CURRENT expands to the email in git config user.email
emails = ["CURRENT"]

[markers]
# Commits containing this string in their message are never rewritten
skip = ["[no-alibi]"]

Commands

rewrite

Rewrites commit timestamps to fit within the configured windows. Operates on commits in the current branch since it diverged from main/master (or the upstream tracking branch), for the current git user's commits only.

git-alibi rewrite [OPTIONS] [REF]
Option Description
--dry-run Preview changes without modifying the repo
-v, --verbose Show all commits in dry-run output, not just changed ones
--no-backup Skip saving a backup before rewriting
--shift DURATION Shift timestamps by a fixed amount instead of fitting windows (e.g. +2h, -5h30m, +5:30)
--timezone TZ Override the timezone (IANA name, e.g. America/Chicago)
--allow-days DAYS Comma-separated days to allow (e.g. MON,TUE,WED,THU,FRI)
--block-days DAYS Comma-separated days to block (e.g. SAT,SUN)
--allow-times RANGES Time ranges to allow (e.g. 09:00-17:00, MON+FRI@09:00-12:00)
--block-times RANGES Time ranges to block
--allow-dates DATES Dates or ranges to allow (e.g. 2024-03-01:2024-03-31)
--block-dates DATES Dates or ranges to block (e.g. 2024-12-25)
--out-of-window How to handle commits outside all windows: nearest (default), previous, next, random
--spacing How to distribute commits within a window: preserve (default), proportional, even, random
--author-emails EMAILS Comma-separated emails to rewrite; CURRENT = git config user.email
--all-authors Rewrite commits by all authors, not just the current user
--all-history Rewrite all reachable history, not just the current branch
--skip-markers MARKERS Comma-separated message markers that exempt a commit (default: [no-alibi])
-f, --force Proceed even if signed commits would be rewritten

Timezone correction with --shift

If you committed in the wrong timezone, shift all timestamps by a fixed offset:

git-alibi rewrite --shift +5:30    # move everything forward 5h30m
git-alibi rewrite --shift -8h      # move everything back 8 hours
git-alibi rewrite --dry-run --shift +2h   # preview first

Opting out of rewriting

Add [no-alibi] anywhere in a commit message to permanently exempt that commit:

fix: correct off-by-one error [no-alibi]

The marker string is configurable via [markers] skip in the config file or --skip-markers on the command line.

restore

Restores commit timestamps from the backup saved before a previous rewrite.

git-alibi restore [OPTIONS] [REF]
Option Description
--dry-run Preview what would be restored without applying
-v, --verbose Show all commits, not just changed ones
--last N Undo the Nth most recent rewrite (default: 1 = last)
--rewrite ID Restore a specific rewrite by ID (see history)
-f, --force Proceed even if signed commits would be rewritten
git-alibi restore              # undo the last rewrite
git-alibi restore --last 2    # undo the second-to-last rewrite
git-alibi restore --rewrite 3 # restore to a specific snapshot ID

history

Shows all recorded rewrites and the exact command to restore each one.

git-alibi history [-v]
Rewrite history — 3 snapshots in .git/alibi/backup.json

  ID    WHEN                     COMMITS  --last  RESTORE
  ───────────────────────────────────────────────────────
  1     2024-01-06 Sat 09:15:00        5       3  alibi restore --last 3
  2     2024-01-07 Sun 14:30:00        3       2  alibi restore --last 2
  3     2024-01-08 Mon 11:15:00        2       1  alibi restore ← latest

Use -v to also list the individual commits and their original timestamps.

config

Opens a config file in $EDITOR, creating it with commented-out defaults if it doesn't exist yet.

git-alibi config local    # .git/alibi/config.toml
git-alibi config global   # ~/.config/alibi/config.toml

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

git_alibi-0.1.0.tar.gz (47.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

git_alibi-0.1.0-py3-none-any.whl (35.8 kB view details)

Uploaded Python 3

File details

Details for the file git_alibi-0.1.0.tar.gz.

File metadata

  • Download URL: git_alibi-0.1.0.tar.gz
  • Upload date:
  • Size: 47.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for git_alibi-0.1.0.tar.gz
Algorithm Hash digest
SHA256 1509acf1a15b22233458e88d0999d56e641cedfe9ae05354dcc02c07447b1521
MD5 2f264b59403ab41fe77213ab4238550a
BLAKE2b-256 3cc0f6f34b1819acffd142a3567425fb203e8f814f778e4ff47d8f0faf3ee032

See more details on using hashes here.

File details

Details for the file git_alibi-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: git_alibi-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 35.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for git_alibi-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 af4db6164b89c7f2fdaedd01e3b8f7fe9b09b2574608bb8c13b279c0dcfb1872
MD5 46827f9ba0b3f073186c8e7e3c5aaba4
BLAKE2b-256 f2eeb8a41c5c69b0c6c6bfc6f3946354df7cbcb908685fa27cf35f813f769933

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page