22

Is there any easy way to postpone GitHub commits?

It would be also nice if these commits will go one after another in 1 hour.
Let's say if I have 5 commits, the first one should appear at 10am, second at 11am, third at 12pm and so on.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
Roman Pushkin
  • 5,639
  • 3
  • 40
  • 58
  • possible duplicate of [How can one change the timestamp of an old commit in Git?](http://stackoverflow.com/questions/454734/how-can-one-change-the-timestamp-of-an-old-commit-in-git) – Sean Apr 28 '15 at 18:48
  • You can set [commits in the future/past](http://stackoverflow.com/a/367475/477563). That should do what you need. – Mr. Llama Apr 28 '15 at 18:50
  • 3
    Why not just...y'know...talk to your employer about this? If you explained that it was on your own time (and potentially on your own hardware) I doubt they'd lodge a complaint. – Makoto Apr 28 '15 at 18:55
  • 2
    This is a good way to get yourself fired. – fuz Apr 28 '15 at 20:17

3 Answers3

34

You can use commit --date argument:

git commit -m "message" --date "Tue Apr 28 23:00:00 2015 +0300"

UPD: there is also pretty cool script for shifting old commits date (you need Perl to run it): https://raw.githubusercontent.com/gitbits/git-shift/master/git-shift

perl git-shift +5h 2e6fd0a9dc98403c4fca638e411b3451cbc66a89

UPD2: You can create custom alias in order to shift all new commits automatically. In order to do that, put the following line into your ~/.bashrc file

alias future-commit='git commit --date "$(date -v +4H)"'

or

alias future-commit='git commit --date "$(date -d +4hours)"'

reload terminal and now you will be able to commit with +4 hours shift:

future-commit -m "future commit"
Roman Pushkin
  • 5,639
  • 3
  • 40
  • 58
Oleksandr Horobets
  • 1,335
  • 14
  • 26
  • 1
    That `--date` sets only the author date, not the committer date, see [my answer](http://stackoverflow.com/a/29927611/1860929). Good job on the perl script.. – Anshul Goyal Apr 28 '15 at 19:40
  • anyway, Github picks it up, even the future date: https://github.com/oleksandr-horobets/git-date-shift/commits/master – Oleksandr Horobets Apr 28 '15 at 19:44
20

You can make commits in any date, time using

GIT_AUTHOR_DATE='your date' GIT_COMMITTER_DATE='your date' git commit -m 'message'

The format for 'your date' is like Fri May 01 19:32:10 2015 -0400.

Note that author and committer are different entities in git terminology, and so both the timestamps need to be set (unlike the options provided in other comments and answers).

In general, the author_date is the one that is picked up by github/in git log etc, and the committer_date is visible when you view all the commit information, like in gitk. If altering the author_date alone works, use the --date option as the other answer points.

Community
  • 1
  • 1
Anshul Goyal
  • 73,278
  • 37
  • 149
  • 186
1

Note: if you need to postpone a commit in a very distant future, Git 2.13.x/Git 2.14 (Q3 2017) will accommodate your need.

Git's source code refers to timestamps as unsigned longs.
On 32-bit platforms, as well as on Windows, unsigned long is not large enough to capture dates that are "absurdly far in the future".

It is perfectly valid by the C standard, of course, for the long data type to refer to 32-bit integers. That is why the time_t data type exists: so that it can be 64-bit even if long is 32-bit.
Git's source code simply uses an incorrect data type for timestamps, is all.

See commit 28f4aee, commit 1e65a98, commit dddbad7 (26 Apr 2017), commit cb71f8b, commit 1aeb7e7 (21 Apr 2017), and commit efac8ac, commit a07fb05, commit e467dc1 (20 Apr 2017) by Johannes Schindelin (dscho).
See commit 3f78971 (08 May 2017) by Ramsay Jones (``).
(Merged by Junio C Hamano -- gitster -- in commit b15667b, 16 May 2017)

use uintmax_t for timestamps

Previously, we used unsigned long for timestamps. This was only a good choice on Linux, where we know implicitly that unsigned long is what is used for time_t.

However, we want to use a different data type for timestamps for two reasons:

  • there is nothing that says that unsigned long should be the same data type as time_t, and indeed, on 64-bit Windows for example, it is not:
    unsigned long is 32-bit but time_t is 64-bit.

  • even on 32-bit Linux, where unsigned long (and thereby time_t) is 32-bit, we want to be able to encode timestamps in Git that are currently absurdly far in the future, even if the system library is not able to format those timestamps into date strings.

So let's just switch to the maximal integer type available, which should be at least 64-bit for all practical purposes these days. It certainly cannot be worse than unsigned long, so...

This is based on commit dddbad7 (part of this patch):

timestamp_t: a new data type for timestamps

Git's source code assumes that unsigned long is at least as precise as time_t. Which is incorrect, and causes a lot of problems, in particular where unsigned long is only 32-bit (notably on Windows, even in 64-bit versions).

So let's just use a more appropriate data type instead.
In preparation for this, we introduce the new timestamp_t data type.

As we will use a data type that is not necessarily identical to time_t, we need to be very careful to use time_t whenever we interact with the system functions, and timestamp_t everywhere else.


Note that, before Git 2.24 (Q4 2019), that new timestamp_t type was flawed.

See commit 2e09c01 (24 Sep 2019) by SZEDER Gábor (szeder).
Helped-by: Johannes Sixt (j6t).
(Merged by Junio C Hamano -- gitster -- in commit 0b4fae5, 09 Oct 2019)

name-rev: avoid cutoff timestamp underflow

When 'git name-rev' is invoked with commit-ish parameters, it tries to save some work, and doesn't visit commits older than the committer date of the oldest given commit minus a one day worth of slop.
Since our 'timestamp_t' is an unsigned type, this leads to a timestamp underflow when the committer date of the oldest given commit is within a day of the UNIX epoch.
As a result the cutoff timestamp ends up far-far in the future, and 'git name-rev' doesn't visit any commits, and names each given commit as 'undefined'.

Check whether subtracting the slop from the oldest committer date would lead to an underflow, and use no cutoff in that case.
We don't have a TIME_MIN constant, dddbad7 (timestamp_t: a new data type for timestamps, 2017-04-26, Git v2.14.0-rc0) didn't add one, so do it now.

Note that the type of the cutoff timestamp variable used to be signed before 5589e87 (name-rev: change a "long" variable to timestamp_t, 2017-05-20, Git v2.14.0-rc0).
The behavior was still the same even back then, but the underflow didn't happen when substracting the slop from the oldest committer date, but when comparing the signed cutoff timestamp with unsigned committer dates in name_rev().
IOW, this underflow bug is as old as 'git name-rev' itself.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250