https://github.com/git-for-windows/git/issues/2206
https://git-scm.com/docs/git-filter-branch
The --env-filter
option can be used to modify committer and/or author identity. For example, if you found out that your commits have the wrong identity due to a misconfigured user.email, you can make a correction, before publishing the project, like this:
git filter-branch --env-filter ' if test "$GIT_AUTHOR_EMAIL" = "root@localhost" then GIT_AUTHOR_EMAIL=john@example.com fi if test "$GIT_COMMITTER_EMAIL" = "root@localhost" then GIT_COMMITTER_EMAIL=john@example.com fi ' -- --all
To restrict rewriting to only part of the history, specify a revision range in addition to the new branch name. The new branch name will point to the top-most revision that a git rev-list of this range will print.
Consider this history:
D--E--F--G--H / / A--B-----C
To rewrite only commits D,E,F,G,H, but leave A, B and C alone, use:
git filter-branch ... C..H
To rewrite commits E,F,G,H, use one of these:
git filter-branch ... C..H --not D git filter-branch ... D..H --not C
Running filter-branch over a range of commits
git filter-branch
does accept range notation, but the end of the range needs to be a reference, not the ID of a commit.
git checkout -b tofilter commitb
git filter-branch .... commita..tofilter
If given just commits, it would not know what ref to update with the filtered branch.
Changing the Date on a Series of Git Commits
Changing the Dates
Now what you need to do is rewrite the history of your branch.
Note: Do not rewrite the history of your repository if you have already shared it. Only do this on a local copy that you have never pushed.
At this point you should make a copy of your local repository as a backup. This could all end in disaster.
To rewrite the history we will use the filter-branch
command in Git.
The general form for filter-branch
is:
git filter-branch --env-filter "<shell code>"
The whole shell code
part is what makes this difficult on Windows.
If you have Cygwin, you are probably better off using it as I believe it would be more straight forward.
The problem with the Windows command prompt is that the shell code is Bash code, but the escaping and quoting between Windows and Bash gets a little dicey.
The following (don’t run this) would change the date on the all the commits:
git filter-branch --env-filter "GIT_AUTHOR_DATE='Mon May 28 10:49:30 2015 -0400'; GIT_COMMITTER_DATE='Mon May 28 10:49:30 2015 -0400';"
If you ignored my warning and ran it anyway, or made another mistake, you can restore the backup:
git reset --hard refs/original/refs/heads/master
However, what is needed is a way to change specific commits. To do that, you need to wrap the --env-filter
in some logic. Specifically an if
statement:
git filter-branch --env-filter "if test $GIT_COMMIT = 'f51ced7692f8509b8b5eb2c47c65cb64aec9f415'; then GIT_AUTHOR_DATE='Mon May 28 10:49:30 2015 -0400'; GIT_COMMITTER_DATE='Mon May 28 10:49:30 2015 -0400'; fi"
Note: On Windows this has to be all on one line. If you break it up, it does not work (unlike on Linux).
If you have to run more than one filter-branch
, you will need to add the -f
switch to force overwritting of the local backup.
When you run this command it will rewrite all of the future commits. That means that they will get new commit ids and the old ones will be invalid, so if you are rewriting multiple commits you need to manually loop. For example (continuing from the previous commands):