From aa6b547f55a1d27cecb7670da614d6683cf8ca08 Mon Sep 17 00:00:00 2001 From: Bill Wood Date: Sun, 1 May 2022 16:48:57 -0400 Subject: [PATCH 1/5] add --newer flag and ignore files in the working tree or index --- Commands.md | 13 ++++++++----- bin/git-utimes | 42 +++++++++++++++++++++++++++++------------- man/git-utimes.md | 18 +++++++++++++----- 3 files changed, 50 insertions(+), 23 deletions(-) diff --git a/Commands.md b/Commands.md index 72e4522..e6307b6 100644 --- a/Commands.md +++ b/Commands.md @@ -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. diff --git a/bin/git-utimes b/bin/git-utimes index 9e45c05..2cc1fc2 100755 --- a/bin/git-utimes +++ b/bin/git-utimes @@ -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 diff --git a/man/git-utimes.md b/man/git-utimes.md index 5ad693a..e3ad079 100644 --- a/man/git-utimes.md +++ b/man/git-utimes.md @@ -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 <>, inspired by Stackexchange comments. +Written by Vitaly Chikunov <>, inspired by Stackexchange comments. Updated by Bill Wood to add --newer flag and ignore files in the working tree or index. ## REPORTING BUGS From 799aa6e19ad7fa89d5b4378c89b5043001d25a28 Mon Sep 17 00:00:00 2001 From: Bill Wood Date: Sun, 1 May 2022 22:01:57 -0400 Subject: [PATCH 2/5] allow modification date updates for symbolic links --- bin/git-utimes | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/bin/git-utimes b/bin/git-utimes index 2cc1fc2..a872e20 100755 --- a/bin/git-utimes +++ b/bin/git-utimes @@ -16,15 +16,13 @@ if [ "$1" = "--touch" ]; then date_flags="-d@" fi for f; do - 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 + 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 -h -t $t $f" >&2 + touch -h -t "$t" "$f" fi fi done From 48beb58670554a937472868fc62282a251c1a22d Mon Sep 17 00:00:00 2001 From: Bill Wood Date: Thu, 5 May 2022 10:43:48 -0400 Subject: [PATCH 3/5] Update Commands.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 罗泽轩 --- Commands.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Commands.md b/Commands.md index e6307b6..5ff92a1 100644 --- a/Commands.md +++ b/Commands.md @@ -1520,7 +1520,7 @@ $ git browse-ci upstream ## git utimes -Change files modification time to their last commit date. Does not touch files that are in the working tree or index. +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. From 41df8dc7f322f6b3ac759e10493e2ca92d1194fc Mon Sep 17 00:00:00 2001 From: Bill Wood Date: Thu, 5 May 2022 11:19:30 -0400 Subject: [PATCH 4/5] updates per request of spacewander --- Commands.md | 8 +++++--- bin/git-utimes | 4 ++-- check_dependencies.sh | 2 +- man/git-utimes.md | 10 +++++----- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/Commands.md b/Commands.md index e6307b6..a644e45 100644 --- a/Commands.md +++ b/Commands.md @@ -1520,9 +1520,9 @@ $ git browse-ci upstream ## git utimes -Change files modification time to their last commit date. Does not touch files that are in the working tree or index. +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. +The `--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 @@ -1536,6 +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 --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 @@ -1546,6 +1547,7 @@ git-extras$ git utimes --newer + touch -d 2019-09-05T12:41:38+08:00 bin/git-changelog + touch -d 2016-11-19T16:41:19+00:00 bin/git-clear [...] + git-extras$ ls -l bin | head total 308 -rwxr-xr-x 1 vt vt 489 Jul 28 2015 git-alias @@ -1559,7 +1561,7 @@ 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. +Note above, that because of the `--newer` flag, the file `git-alias` was not touched since its modified date is earlier than the commit date. ## git abort diff --git a/bin/git-utimes b/bin/git-utimes index a872e20..0a5f1f4 100755 --- a/bin/git-utimes +++ b/bin/git-utimes @@ -5,7 +5,7 @@ if [ "$1" = "--touch" ]; then # Internal use option only just to parallelize things. newer_flag="" - [ "$2" = "--newer" ] || [ "$2" = "-n" ] && newer_flag="true" + [ "$2" = "--newer" ] && newer_flag="true" shift 2 bsd=$(date -j > /dev/null 2>&1 && echo 'true') if [ -n "$bsd" ]; then @@ -36,7 +36,7 @@ else # 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') \ + 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' \ diff --git a/check_dependencies.sh b/check_dependencies.sh index 6399510..05c2f73 100755 --- a/check_dependencies.sh +++ b/check_dependencies.sh @@ -6,5 +6,5 @@ err() { } if ! command -v column >/dev/null 2>&1; then - err "Need to install dependency 'column' before installation" + err "Need to install dependency 'column' before installation (can be found in bsdmainutils)" fi diff --git a/man/git-utimes.md b/man/git-utimes.md index e3ad079..9e9cf36 100644 --- a/man/git-utimes.md +++ b/man/git-utimes.md @@ -3,15 +3,15 @@ git-utimes(1) -- Change files modification time to their last commit date ## SYNOPSIS -`git-utimes` [-n, --newer] +`git-utimes` [--newer] ## DESCRIPTION - Change files modification time to their last commit date. Does not touch files that are in the working tree or index. + Change files modification time to their last commit date. Does not touch files that are in the working tree or index. ## OPTIONS - -n, --newer + --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. @@ -23,11 +23,11 @@ git-utimes(1) -- Change files modification time to their last commit date * As above, but preserve original modification time of files that were committed from local repo: - $ git utimes -n + $ git utimes --newer ## AUTHOR -Written by Vitaly Chikunov <>, inspired by Stackexchange comments. Updated by Bill Wood to add --newer flag and ignore files in the working tree or index. +Written by Vitaly Chikunov <>, inspired by Stackexchange comments. Updated by Bill Wood <> to add `--newer` flag and ignore files in the working tree or index. ## REPORTING BUGS From 42fd8a9e725bcdb670ec46f5a03a465b6fd14c57 Mon Sep 17 00:00:00 2001 From: Bill Wood Date: Fri, 6 May 2022 08:33:30 -0400 Subject: [PATCH 5/5] quote mod_s and git_s integer vars --- bin/git-utimes | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/git-utimes b/bin/git-utimes index 0a5f1f4..80d9d33 100755 --- a/bin/git-utimes +++ b/bin/git-utimes @@ -18,8 +18,8 @@ if [ "$1" = "--touch" ]; then 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 ] || [ ! -n "$newer_flag" ]; then + 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 -h -t $t $f" >&2 touch -h -t "$t" "$f"