|
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