我正在尝试检索修改/编辑我提供的文件列表的最新提交。
在实践中,如果我有a.txt
和b.txt
,其中a.txt
已于昨天修改且b.txt
已在2小时前修改过,我想获得最新信息编辑b.txt
。
到目前为止,这是我的脚本:
for file in components/*/index.jsx
do
# 1. Get the dirname of the current file
dir=`dirname $file`
# 2. Get a space separated list of files to check in $dir
files=`find $dir -type f | grep -E -v "demo.jsx|.test.jsx|meta.json|__snapshots__" | tr '\n' ' '`
# 3. Get the most recent commit that touched any of the listed files
commit=`git log -n 1 --pretty=format:%H -- $files | cat`
# 4. Get the version of the package.json at the specific $commit
version=`git show $commit:packages/react-components/package.json | cat | grep -m 1 version`
# 5. Insert the version in the meta.json of the component
sed -i'' -e "2s/.*/$version/" $dir/meta.json
# 6. Remove the backup file generated by sed
rm $dir/meta.json-e
done
问题在于步骤#3,如果我提供多个文件,它根本不会返回任何提交。
这是有问题的步骤的日志:
❯ echo $files
components/Foobar/index.jsx components/Foobar/index.sss
❯ git log -n 1 --pretty=format:%H -- $files | cat
# nothing
如果我跑了:
❯ git log -n 1 --pretty=format:%H -- components/Foobar/index.jsx components/Foobar/index.sss | cat
93012738e776f4ffe920161ba61501ed84b815a5
我得到了提交哈希......
想法?
更新: 如果我跑:
`echo "git log -n 1 --pretty=format:%H -- $files"`
它打印提交哈希,为什么?
答案 0 :(得分:2)
这非常奇怪。以下是一些可以尝试的事情。
说明:
for
循环多次运行并产生大量输出,请暂时将components/*/index.jsx
替换为components/Foobar/index.jsx
(或者使用哪个文件触发问题)。git
命令)。代码段:
检查哪个shell正在运行脚本
echo "$SHELL"
ls -l "$SHELL"
预期输出:/bin/sh
,可能是指向bash
或dash
的符号链接。如果它是到另一个shell的符号链接(例如zsh
),那将是一个问题,因为其他shell以不同的方式扩展变量。
仔细检查原始命令中"
周围是否有引号($files
)。
检查$IFS
是否正确。
echo -n "$IFS" | xxd -p
预期输出:20090a
(<space><tab><newline>
的十六进制)
(我知道我已经要求你这样做了,但是请从脚本再次执行。)
$IFS
控制单词拆分,如果它是一个奇怪的值,会导致问题。
检查文件是否存在:
ls components/Foobar/index.jsx components/Foobar/index.sss
预期输出:ls
应列出这两个文件
如果您收到“No such file or directory”错误,请检查该点脚本的工作目录以及签出的git分支。
尝试使用files
变量,设置为字符串:
files="components/Foobar/index.jsx components/Foobar/index.sss"
ls $files
预期输出:ls
应列出两个文件。
如果出现错误,例如
ls: cannot access components/Foobar/index.jsx components/Foobar/index.sss: No such file or directory
然后你的shell出了问题,因为它没有对未加引号的变量进行单词拆分。
尝试在反引号中运行ls
。
files="components/Foobar/index.jsx components/Foobar/index.sss"
output=`ls $files`
echo "$output"
预期输出:两个文件 如果你得到一个“没有这样的文件或目录”错误,那么你的shell就会被破坏,并且不会在反引号中正确地进行变量扩展。
使用find
代替文字字符串:
ls $files
与代码段5不同,此代码段允许$files
保留脚本中第2步的值。
预期输出:ls
应列出与前一个代码段相同的两个文件
如果您收到错误(没有此类文件或目录),则脚本的第2步出现问题。使用$files
检查echo -n "$files" | od -c
的值并发布。
使用文字文件参数尝试git
命令:
git log -n 1 --pretty=format:%H -- components/Foobar/index.jsx components/Foobar/index.sss | cat
echo # output of previous command doesn't have a trailing newline
预期输出:提交哈希。
尝试使用$files
变量,设置为字符串:
files="components/Foobar/index.jsx components/Foobar/index.sss"
git log -n 1 --pretty=format:%H -- $files | cat
echo # output of previous command doesn't have a trailing newline
预期输出:提交哈希。
使用find
代替文字字符串:
git log -n 1 --pretty=format:%H -- $files | cat
echo # output of previous command doesn't have a trailing newline
预期输出:提交哈希。
尝试脚本中的原始命令:
commit=`git log -n 1 --pretty=format:%H -- $files | cat`
echo "$commit"
预期输出:提交哈希。
答案 1 :(得分:1)
将此作为答案发布,但主要是解决方法:
for file in components/*/index.jsx
do
dir=`dirname $file`
files=`find $dir -type f | grep -E -v "demo.jsx|meta.json|.test.jsx|__snapshots__" | tr '\n' ' '`
# We basically print the command as string, and evaluate it with backtricks
# Use only if you have complete control over the project structure!
commit=`$(echo git log -n 1 --pretty=format:%H -- $files) | cat`
version=`git show $commit:packages/react-components/package.json | cat | grep -m 1 version`
sed -i'' -e "2s/.*/$version/" $dir/meta.json
rm $dir/meta.json-e
done
我不知道为什么需要它,但它似乎至少起作用。