readlink -f,根据其手册页:
"通过递归地跟随给定名称的每个组件中的每个符号链接来规范化[s];除了最后一个组件之外的所有组件都必须存在"
我想要一个等同于" readlink -f"对于Git。换句话说,这是一种在存储库中给定提交的路径中跟踪每个符号链接的方法,最后是规范版本的路径。
我已经编写了我自己的函数(如下所示),但我想知道Git是否具有执行相同操作的本机功能。并且,如果它没有,也许值得考虑在新版本的Git中包含相同的功能。感谢。
SYMLINK_FILE_TYPE_OCTAL="12"
MAX_SYMLINK_COUNT=10
git-is-symlink() {
local commit="$1"
local dir="$2"
local base="$3"
git ls-tree "${commit}:$dir" "$base" | grep -q -P "^$SYMLINK_FILE_TYPE_OCTAL"
}
git-get-symlink-target() {
local commit="$1"
local dir="$2"
local base="$3"
if test -z "$dir"; then
local path="$base"
else
local path="$dir/$base"
fi
git cat-file blob "$commit:$path"
}
git-resolve-path-recursive() {
local commit="$1"
local resolved_prefix="$2"
local segment_to_be_resolved="$3"
local unresolved_suffix="$4"
local symlink_count="$5"
if test -z "$segment_to_be_resolved" && test -z "$unresolved_suffix"; then
echo "$resolved_prefix"
return
fi
if test "$symlink_count" -gt "$MAX_SYMLINK_COUNT"; then
echo "Exceeded symlink count of $MAX_SYMLINK_COUNT on '$prefix' '$segment_to_be_resolved'" >&2
exit 1
fi
if test -n "$segment_to_be_resolved" && git-is-symlink "$commit" "$resolved_prefix" "$segment_to_be_resolved"; then
local symlink_target="$(git-get-symlink-target "$commit" "$resolved_prefix" "$segment_to_be_resolved")"
git-resolve-path-recursive "$commit" "$resolved_prefix" "$symlink_target" "$unresolved_suffix" $((++symlink_count))
else
if test -z "$resolved_prefix"; then
local new_resolved_prefix="$segment_to_be_resolved"
else
local new_resolved_prefix="$resolved_prefix/$segment_to_be_resolved"
fi
local new_segment_to_be_resolved="$(echo "$unresolved_suffix" | cut -d / -f 1)"
local new_unresolved_suffix="$(echo "$unresolved_suffix" | cut -s -d / -f 2-)"
git-resolve-path-recursive "$commit" "$new_resolved_prefix" "$new_segment_to_be_resolved" "$new_unresolved_suffix" 0
fi
}
## Main entry point
## USAGE: git-resolve-path COMMIT PATH
git-resolve-path() {
local commit="$1"
local path="$2"
git-resolve-path-recursive "$commit" "" "" "$path" 0
}
使用示例:
> mkdir -p targetdir
> ln -s targetdir linkdir
> touch targetdir/targetfile
> ln -s targetfile targetdir/linkfile
> git add targetdir linkdir targetdir/targetfile targetdir/linkfile
> git commit -m "Add files"
> git-resolve-path HEAD linkdir/linkfile
targetdir/targetfile