tr3online
tr3online

Reputation: 1429

Change GIT_AUTHOR_DATE/GIT_COMMITTER_DATE date of a specific previous commit on git

As per this post, it is recommended to do:

git filter-branch --env-filter \
    'if [ $GIT_COMMIT = <commit hash here> ]
     then
         export GIT_AUTHOR_DATE="Fri Jan 2 21:38:53 2009 -0800"
         export GIT_COMMITTER_DATE="Sat May 19 01:01:01 2007 -0700"
     fi'

to change the GIT_AUTHOR_DATE and GIT_COMMITTER_DATE of a previous commit.

Is there a way to do this targeting the exact branch/commit, so I don't have to filter through all my branches? This takes a while on one of my projects.

Upvotes: 1

Views: 2942

Answers (1)

torek
torek

Reputation: 487993

That filter does target the exact commit (and runs only on the current branch). You can restrict it to stop copying at other (earlier) points; and if the commit is close to the branch tip, that will help speed a lot. Remember, the current branch contains every commit that is reachable from its tip, even if those commits are on other branches. For instance:

...--o--o--*--o--o--o   <-- master
            \
             o--o   <-- develop (HEAD)

There are two commits that are only on develop here, three commits that are only on master, and many (at least three, plus whatever ... represents) that are on both branches, with the most recent of those being commit *.

If you know the hash ID of commit * you can write:

git filter-branch --env-filter \
    [snip actual filter] \
    HEAD ^<hash>

to tell Git to stop traversing backwards upon reaching commit *; or you can use the simpler:

git filter-branch --env-filter \
    [snip actual filter] \
    HEAD ^master

This excludes all three master-only commits from the filtering, as well as commit * and earlier. That's quite safe since they're already not part of the action anyway: we merely use the name master as a short-cut to identify all commits reachable from master (so that we retain only commits reachable from develop and not those reachable from both names).

(Remember, Git "reaches" commits by starting at the given name(s)—in this case develop and master—and working backwards. A prefix hat/caret ^ character means "exclude these", and git filter-branch only updates what it calls positive references, i.e., names that mean "include" rather than names that mean "exclude". So after filter-branch has copied every commit it's going to copy, it replaces the name develop, which is a positive reference, but not the name master, which—because of the ^ prefix—is a negative reference.)

Upvotes: 1

Related Questions