add --newer flag and ignore files in the working tree or index

This commit is contained in:
Bill Wood 2022-05-01 16:48:57 -04:00
parent d2a09c1753
commit aa6b547f55
3 changed files with 50 additions and 23 deletions

View file

@ -1520,12 +1520,14 @@ $ git browse-ci upstream
## git utimes
Change files modification time to their last commit date.
Change files modification time to their last commit date. Does not touch files that are in the working tree or index.
The `-n` or `--newer` flag preserves the original modification time of files that were committed from the local repo, by only touching files that are newer than their last commit date.
```bash
git-extras$ ls -l bin | head
total 308
-rwxr-xr-x 1 vt vt 489 Nov 8 13:56 git-alias
-rwxr-xr-x 1 vt vt 489 Jul 28 2015 git-alias
-rwxr-xr-x 1 vt vt 1043 Nov 8 13:56 git-archive-file
-rwxr-xr-x 1 vt vt 970 Nov 8 13:56 git-authors
-rwxr-xr-x 1 vt vt 267 Nov 8 13:56 git-back
@ -1534,8 +1536,7 @@ total 308
-rwxr-xr-x 1 vt vt 6282 Nov 8 13:56 git-bulk
-rwxr-xr-x 1 vt vt 18561 Nov 8 13:56 git-changelog
-rwxr-xr-x 1 vt vt 215 Nov 8 13:56 git-clear
git-extras$ git utimes
+ touch -d 2015-08-09T19:27:49+08:00 bin/git-alias
git-extras$ git utimes --newer
+ touch -d 2020-05-22T10:40:29+08:00 bin/git-archive-file
+ touch -d 2017-05-05T16:02:09+08:00 bin/git-authors
+ touch -d 2020-02-23T11:41:54+08:00 bin/git-back
@ -1547,7 +1548,7 @@ git-extras$ git utimes
[...]
git-extras$ ls -l bin | head
total 308
-rwxr-xr-x 1 vt vt 489 Aug 9 2015 git-alias
-rwxr-xr-x 1 vt vt 489 Jul 28 2015 git-alias
-rwxr-xr-x 1 vt vt 1043 May 22 05:40 git-archive-file
-rwxr-xr-x 1 vt vt 970 May 5 2017 git-authors
-rwxr-xr-x 1 vt vt 267 Feb 23 2020 git-back
@ -1558,6 +1559,8 @@ total 308
-rwxr-xr-x 1 vt vt 215 Nov 19 2016 git-clear
```
Note above, `git-alias` was not touched because of the `--newer` flag.
## git abort
Abort current rebase, merge or cherry-pick, without the need to find exact command in history.

View file

@ -2,20 +2,30 @@
#
# Change files modification time to their last commit date
#
if [ "$1" = --touch ]; then
if [ "$1" = "--touch" ]; then
# Internal use option only just to parallelize things.
shift
newer_flag=""
[ "$2" = "--newer" ] || [ "$2" = "-n" ] && newer_flag="true"
shift 2
bsd=$(date -j > /dev/null 2>&1 && echo 'true')
if [ -n "$bsd" ]; then
stat_flags="-f %m"
date_flags="-r"
else
stat_flags="-c %Y"
date_flags="-d@"
fi
for f; do
iso_t=$(git --no-pager log --no-renames --pretty=format:%cI -1 @ -- "$f" 2>/dev/null)
if [ -n "$iso_t" ]; then
bsd=$(date -j > /dev/null 2>&1 && echo 'true')
if [ "$bsd" == "true" ]; then
t=$(date -j -f %Y-%m-%dT%H:%M:%S "$iso_t" +%Y%m%d%H%M.%S)
else
t=$(date -d"$iso_t" +%Y%m%d%H%M.%S)
if [ ! -L "$f" ]; then
git_s=$(git --no-pager log --no-renames --pretty=format:%ct -1 @ -- "$f" 2>/dev/null)
mod_s=$(stat $stat_flags "$f" 2>/dev/null)
if [ -n "$git_s" ] && [ -n "$mod_s" ] && [ $mod_s -ne $git_s ]; then
if [ $mod_s -gt $git_s ] || [ ! -n "$newer_flag" ]; then
t=$(date $date_flags$git_s '+%Y%m%d%H%M.%S')
echo "+ touch -t $t $f" >&2
touch -t "$t" "$f"
fi
fi
echo "+ touch -t $t $f" >&2
touch -t "$t" "$f"
fi
done
else
@ -25,6 +35,12 @@ else
# because all args will go into single worker.
NPROC=$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || getconf _NPROCESSORS_ONLN 2>/dev/null)
# shellcheck disable=SC2086
git ls-tree -z -r -t --name-only @ \
| xargs -0 -P${NPROC:-1} -n${NPROC:-1} $opt_r git utimes --touch
# don't touch files that have been modified in the worktree or index
# bsd doesn't have `-z` option for `comm` and `cut`, so use `tr` as work around
prefix="$(git rev-parse --show-prefix) "
comm -23 <(git ls-tree -z -r --name-only --full-name @ | tr '\0' '\n') \
<(git status -z --porcelain | tr '\0' '\n' | cut -c 4- | sort) \
| cut -c ${#prefix}- \
| tr '\n' '\0' \
| xargs -0 -P${NPROC:-1} -n 24 $opt_r git utimes --touch "$1"
fi

View file

@ -3,23 +3,31 @@ git-utimes(1) -- Change files modification time to their last commit date
## SYNOPSIS
`git-utimes`
`git-utimes` [-n, --newer]
## DESCRIPTION
Change files modification time to their last commit date.
Change files modification time to their last commit date. Does not touch files that are in the working tree or index.
## OPTIONS
No options needed.
-n, --newer
Preserves the original modification time of files that were committed from the local repo, by only touching files that are newer than their last commit date.
## EXAMPLES
git utimes
* Update all files' modification time to their last commit date, except those in working tree or index:
$ git utimes
* As above, but preserve original modification time of files that were committed from local repo:
$ git utimes -n
## AUTHOR
Written by Vitaly Chikunov &lt;<vt@altlinux.org>&gt;, inspired by Stackexchange comments.
Written by Vitaly Chikunov &lt;<vt@altlinux.org>&gt;, inspired by Stackexchange comments. Updated by Bill Wood to add --newer flag and ignore files in the working tree or index.
## REPORTING BUGS