News for hackers. Stuff that matters.
Re:Back dating Git commits based on file modification dates by susam on Saturday August 03, 2024 @11:44AM (#41147245)
Not exactly what's in this original post but here's a little shell function that could be useful to conveniently backdate Git commits:

  dated() {
      date=$1
      shift 1
      set -x
      GIT_AUTHOR_DATE="$date" GIT_COMMITTER_DATE="$date" "$@"
      unset date
  }
Some usage examples:

  dated "1990-01-01 10:10" git commit
  dated "1990-01-01 10:10:00 +0100" git commit
  dated "1990-01-01 10:10:10 +0100" git commit --amend
  dated "1990-01-01 10:10:10 +0100" git commit --amend --reset-author
Re:Back dating Git commits based on file modification dates by Izkata on Saturday August 03, 2024 @12:41PM (#41147631)
If all you want is author date (which I think is more correct), then just this works fine:

  git commit --date '1990-01-01 10:10'
Re:Back dating Git commits based on file modification dates by j0057 on Saturday August 03, 2024 @05:37PM (#41149442)
IIRC the GitHub UI started showimg commit date instead of author date some years ago.
Re:Back dating Git commits based on file modification dates by thaliaarchi on Saturday August 03, 2024 @12:55PM (#41147700)
I use the following to create a commit using the latest modification date of the staged files. If you put it in your PATH as git-tcommit, you can invoke it as `git tcommit`. If GIT_AUTHOR_DATE or GIT_COMMITTER_DATE is passed, it overrides the modified time, and it honors TZ. It works with GNU or BSD.

    #!/usr/bin/env bash
    set -eEuo pipefail

    # `git commit`, using the latest file modification time as the commit and author
    # dates, when GIT_AUTHOR_DATE or GIT_COMMITTER_DATE, respectively, is not set.

    # Use fractional seconds when available to display the newest file more
    # accurately, even though Git only uses seconds.
    if which gstat >/dev/null; then
      stat=(gstat --format='%.Y %n') # Detected aliased GNU coreutils
    elif stat --version 2>/dev/null | grep -q 'GNU coreutils'; then
      stat=(stat --format='%.Y %n') # Detected GNU coreutils
    else
      stat=(stat -f '%m %N') # Fallback to BSD-style, which only reports seconds
    fi

    # Select the latest modified time of all staged files, excluding deletions.
    modified="$(
      cd "$(git rev-parse --show-toplevel)" &&
      git diff --staged --diff-filter=d --name-only -z |
        xargs -0 "${stat[@]}" |
        sort -rn |
        head -1
    )"

    modified_seconds=
    if [[ -n $modified ]]; then
      modified_seconds="${modified%% *}"
      modified_file="${modified#* }"
      modified_date="$(date -r "${modified_seconds%.*}" +'%Y-%m-%d %H:%M:%S %z')"
      echo "Modify date: $modified_date ($modified_file)"
    fi
    author_seconds="$modified_seconds"
    committer_seconds="$modified_seconds"
    if [[ -n ${GIT_AUTHOR_DATE+.} ]]; then
      echo "Author date: ${GIT_AUTHOR_DATE:-now}"
    fi
    if [[ -n ${GIT_COMMITTER_DATE+.} ]]; then
      echo "Commit date: ${GIT_COMMITTER_DATE:-now}"
    else
      last_commit_seconds="$(git show -s --format=%at HEAD 2>/dev/null || echo 0)"
      if [[ $modified_seconds < $last_commit_seconds ]]; then
        committer_seconds=
        echo "Commit date: now (last commit: $(git show -s --format=%ai HEAD 2>/dev/null))"
      fi
    fi

    GIT_AUTHOR_DATE="${GIT_AUTHOR_DATE-"$author_seconds"}" \
    GIT_COMMITTER_DATE="${GIT_COMMITTER_DATE-"$committer_seconds"}" \
    exec git commit "$@"