Norman Gray
Norman Gray

Reputation: 12514

Mercurial: amend previous commit dates

Is there a way of changing the commit dates of multiple draft changesets? In particular, changesets before the last one.

I can change the commit date of the last commit with hg ci --amend -d xxx, but can't do so for any earlier ones.

This is obviously non-trivial, since the changeset date is one of the inputs to the changeset hash (where is this authoritatively documented, by the way?), and so a change here would change the hashes of all of a changeset's descendants. Since these are draft changesets, however, that would be OK.

It doesn't seem possible to do this using histedit.

I can guess that rebase might be able to do this sort of thing, but the associated help-text doesn't give any pointers, which suggests that it's at least exotic.

(The problem I'm trying to deal with is that some code is being edited and committed on a machine which is, deliberately, not network connected and which is frequently rebooted; that means that its notion of the system time can be wrong, and sometimes very wrong – as in 1970! – unless someone remembers to set the system date by hand to a reasonable value. While this doesn't matter to the topology of the commit graph, it would be at least nice, for everyone's sake, if the dates bore some relation to reality. Hence my wish to fix this in a ‘review before push’ step.)

Upvotes: 4

Views: 857

Answers (2)

Mark Jeronimus
Mark Jeronimus

Reputation: 9541

For those using TortoiseHG (which doesn't know the evolve extension, and even if it did, there's a simpler way),

Use the mq extension.

  1. Make sure your working directory is clean, (protip: use the shelve extension)
  2. Import all changesets into MQ that you want to change,
  3. Double-click on any changeset that you want to change, so it becomes the top applied one,
  4. Use the Options button to the left of the QRefresh button to set a new date/time,
  5. Hit QRefresh,
  6. Repeat from 3.
  7. Don't forget to uncheck the date change in the options dialog, lest bad things happen.

Upvotes: -1

planetmaker
planetmaker

Reputation: 6044

Well, there's one approach which you already lined-out yourself basically, but it requires activation of the evolve extension: Set the date for one commit, and rebase all subsequent ones, and repeat until you have set the date for each. Assuming linear history:

hg update -rOLDEST_UNCHANGED
hg commit --amend --date DATA
hg rebase -b(OLDEST_UNCHANGED+1) -dtip

rinse and repeat with increasing the changesetID by one in each step. If your history is not linear, you will have to pay attention to the revisions you rebase and which you update to.

The second alternative, but not much better, is is making use of the evolve command from the evolve extension. That helps you with this process, making the steps outlined above slightly easier:

Still you have to start with the first of those commits you want to refresh:

hg update --rev OLDEST_UNCHANGED
hg commit --amend --date DATE
hg evolve --all

And repeat this process again with increasing changesetID until each commit has the date you want.

(If there is some way to set/refresh the commit date using evolve for all commits it evolves, I'm happy to learn - it definitely is a feature request otherwise)

Upvotes: 2

Related Questions