Fuzz Git commit timestamps & timezones
No installation is necessary, however if you put the script in your
PATH
, you could run the script as a custom Git command; e.g.
$ cp git-futz ~/bin/
$ git futz -h
Inside your repo before pushing your unpublished commits, run the script like this:
$ git-futz [--no-tz] [<last-public-commit>]
git-futz
will rewrite the timestamps such that they are evenly
distributed between the timestamp of the <last-public-commit>
and
now.
Optionally, it also assigns a timezone randomly, i.e. if you run it
today it might choose London, and on a subsequent call tomorrow it
could pick Tokyo. This however works only on Linux (needs: tzdata
,
find
& shuf
). If the tzdata
database cannot be found, this
feature is disabled.
If you want to disable the feature explicitly, you can pass the
optional flag --no-tz
.
Note that <last-public-commit>
is optional. If it is not provided,
the following heuristic will be applied to find the last public
commit.
-
identify remote associated to the current branch:
my_remote
-
find the remote head it is configured to merge with:
refs/heads/branch
-
find the last public commit using:
my_remote/branch..HEAD
; note the 2 dots, it means in the case of diverging histories, the last common ancestor will be picked- straight line history:
B
,C
,D
will be rewrittenpublic private --> A ----- B ----- C ----- D
- diverging history:
F
,G
,H
will be rewrittenA ----- B ----- C ----- D ----- E (public) \ F ----- G ----- H private -->
- straight line history:
- POC: works after some
sed
magic π- depends on Python for date arithmetic π
- Reimplement date arithmetic using integer maths in Bash π
- Add timezone randomisation
- Make timezone randomisation optional; improves portability β¨
- Bug fix: was reading commit timestamp with
git-show
instead ofgit-log
πΆ - Preserve committer name & email π₯
- Document various install options
- Add automatic upstream detection heuristic π
-
Q: How can I run
git-futz
automatically before agit-push
? -
A: You could write a git alias that runs
git-futz
before doing a push.[alias] futzy-push = !git futz && git push
-
Q: Can I install the script as a git hook?
-
A: Unfortunately currently I have not found a way to do this, since the script rewrites history, and the
pre-push
hook (see:.git/hooks/pre-push.sample
) runs after determining the commits that should be pushed. -
Q: Can I schedule running
git-futz
andgit-push
to also not reveal when I ran the command? -
A: This is a bit tricky, I'm not certain yet what would be the best practice. Note that
git-futz
only alters the timestamp in the commit history. When yougit-push
, your remote forge (GitHub, GitLab, etc) can record the time.On GitHub, this is sometime shown as a notification on the repository page:
@username pushed branch
branch_name
XYZ minutes agoI don't think this can be avoided. So to "poison" this information, you could schedule a cron job at your desired time. Something like this should work:
cd /path/to/repo && git futz && git push