|
1 | | -#!/bin/bash |
| 1 | +#!/bin/sh |
2 | 2 |
|
3 | 3 | # |
4 | 4 | # Sets the modification times of the given files and the files in the given |
@@ -27,14 +27,30 @@ apply_commit_time() { |
27 | 27 | fi |
28 | 28 | } |
29 | 29 |
|
| 30 | +# Check if the shell supports the "-d" option for the `read` built-in: |
| 31 | +# shellcheck disable=SC2039 |
| 32 | +if printf '%s\0' 1 2 | read -r -d '' 2>/dev/null; then |
| 33 | + iterate() { |
| 34 | + # Disable the internal field separator (IFS) and iterate over the null byte |
| 35 | + # separated file paths using the "-d" option of the `read` built-in: |
| 36 | + while IFS= read -r -d '' FILE; do apply_commit_time "$FILE"; done |
| 37 | + } |
| 38 | +else |
| 39 | + iterate() { |
| 40 | + # Transform the null byte separated files paths into command-line arguments |
| 41 | + # to the script itself via `xargs`. |
| 42 | + # The system-defined command-line arguments constraints will limit the |
| 43 | + # number of files that can be processed for a given directory, which should |
| 44 | + # be below the number defined via "-n" option for xargs: |
| 45 | + xargs -0 -n 100000 "$0" |
| 46 | + } |
| 47 | +fi |
| 48 | + |
30 | 49 | while [ $# -gt 0 ]; do |
31 | 50 | # Is the argument a directory path? |
32 | 51 | if [ -d "$1" ]; then |
33 | | - # The "-z" option of `git ls-tree` outputs NUL byte separated file paths, |
34 | | - # which can be iterated over with the "-d" option of the `read` built-in. |
35 | | - # Since this option not available in POSIX shell, bash is required: |
36 | | - git ls-tree -r -z --name-only HEAD -- "$1" | while IFS= read -d '' -r FILE |
37 | | - do apply_commit_time "$FILE"; done |
| 52 | + # The "-z" option of `git ls-tree` outputs null byte separated file paths: |
| 53 | + git ls-tree -r -z --name-only HEAD -- "$1" | iterate |
38 | 54 | # Else is the argument a path to a readable file? |
39 | 55 | elif [ -r "$1" ]; then |
40 | 56 | apply_commit_time "$1" |
|
0 commit comments