What I would really like is a Git equivalent to Mercurial's "fold" operation. I usually make a bunch of commits as I work, just as checkpoints, which I then want to turn into a single final commit when it's done, which could be quite some time later, e.g. "started on thing", "broke it", "broke it more", "Add thing to improve foo of bar".
Mercurial's "histedit" command offers two operations to combine the commits: "fold" and "roll", where "fold" brings the earlier commit into the later commit and "roll" does the reverse. The "fold" operation does exactly what I want in this case: It brings all the changes into the final commit from when I actually finished it, using the commit date of that commit.
Git's "rebase -i" command offers "squash" and "fixup" and "fixup -c" and "fixup -C", but they all do the same thing as "roll", i.e. they keep the earliest commit's date, the date when I started working on the thing and not the date when I finished working on it. (So I then cut and paste the correct date and update the commit afterwards. This may not be the best way to do it.)
That is an interesting desire to use a later commit date rather than an earlier one. So many prefer that commit date of when an effort started.
One way to accomplish that is to reorder the commmits in `rebase -i`: "pick" the last commit first and squash/fixup the rest after. That can produce some very weird merge conflicts, but it works well more often than you might think, too.
At the very least, you can do your hand editing of the commits during the rebase instead of after by switching the earliest commit from "pick" to "edit" to have the full power to amend the commit before it moves on (with `git rebase --continue` when you are satisfied). (Versus "reword" if you just want to change the commit message only.)
Also, instead of naming commits things like "broke it" and "broke it more" an option is to use `git commit --fixup={previous commit hash}`. That auto-generates a "fixup!" name based on the previous commit and auto-marks it as a fixup if you use the `--autosquash` flag to rebase.