mirror of
https://github.com/tj/git-extras.git
synced 2026-09-10 15:36:21 -04:00
44 lines
1.6 KiB
Bash
Executable file
44 lines
1.6 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
#
|
|
# Change files modification time to their last commit date
|
|
#
|
|
if [ "$1" = "--touch" ]; then
|
|
# Internal use option only just to parallelize things.
|
|
newer_flag=""
|
|
[ "$2" = "--newer" ] && 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
|
|
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" ] || [ -z "$newer_flag" ]; then
|
|
t=$(date $date_flags$git_s '+%Y%m%d%H%M.%S')
|
|
echo "+ touch -h -t $t $f" >&2
|
|
touch -h -t "$t" "$f"
|
|
fi
|
|
fi
|
|
done
|
|
else
|
|
opt_r=$(xargs -r false < /dev/null > /dev/null 2>&1 && echo '-r')
|
|
|
|
# `-n` should be limited or parallelization will not give effect,
|
|
# 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)
|
|
# 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' | sort) \
|
|
<(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
|