[PATCH v2] feat: add the possibility to create relative symlink

Cyril Levis git at levis.name
Fri Dec 30 11:53:33 UTC 2022


I known several people doing this manually and myself.

This work well with android app too.

Thanks for this cool toy !
---
 man/pass.1            |  6 ++++++
 src/password-store.sh | 36 ++++++++++++++++++++++++++++++++++++
 2 files changed, 42 insertions(+)

diff --git a/man/pass.1 b/man/pass.1
index a555dcb..bcc34a3 100644
--- a/man/pass.1
+++ b/man/pass.1
@@ -164,6 +164,12 @@ silently overwrite \fInew-path\fP if it exists. If \fInew-path\fP ends in a
 trailing \fI/\fP, it is always treated as a directory. Passwords are selectively
 reencrypted to the corresponding keys of their new destination.
 .TP
+\fBln\fP [ \fI--force\fP, \fI-f\fP ] \fIsrc-path\fP \fIdst-path\fP
+Link the password or directory named \fIsrc-path\fP to \fIdst-path\fP. This
+command is alternatively named \fBlink\fP. If \fI--force\fP is specified,
+silently overwrite \fIdst-path\fP if it exists. If \fIdst-path\fP ends in a
+trailing \fI/\fP, it is always treated as a directory.
+.TP
 \fBgit\fP \fIgit-command-args\fP...
 If the password store is a git repository, pass \fIgit-command-args\fP as arguments to
 .BR git (1)
diff --git a/src/password-store.sh b/src/password-store.sh
index 22e818f..e95802c 100755
--- a/src/password-store.sh
+++ b/src/password-store.sh
@@ -306,6 +306,8 @@ cmd_usage() {
 	        Renames or moves old-path to new-path, optionally forcefully, selectively reencrypting.
 	    $PROGRAM cp [--force,-f] old-path new-path
 	        Copies old-path to new-path, optionally forcefully, selectively reencrypting.
+	    $PROGRAM ln [--force,-f] old-path new-path
+	        Link src-path to dst-path, optionally forcefully.
 	    $PROGRAM git git-command-args...
 	        If the password store is a git repository, execute a git command
 	        specified by git-command-args.
@@ -649,6 +651,39 @@ cmd_copy_move() {
 	fi
 }

+cmd_link() {
+	local opts force=0
+	opts="$($GETOPT -o f -l force -n "$PROGRAM" -- "$@")"
+	local err=$?
+	eval set -- "$opts"
+	while true; do case $1 in
+		-f|--force) force=1; shift ;;
+		--) shift; break ;;
+	esac done
+	[[ $# -ne 2 ]] && die "Usage: $PROGRAM $COMMAND [--force,-f] old-path new-path"
+	check_sneaky_paths "$@"
+	local src_path="$PREFIX/${1%/}"
+	local src_dir="$src_path"
+	local dst_path="$PREFIX/$2"
+
+	if ! [[ -f $src_path.gpg && -d $src_path && $1 == */ || ! -f $src_path.gpg ]]; then
+		src_dir="${src_path%/*}"
+		src_path="${src_path}.gpg"
+	fi
+	echo "$src_path"
+	[[ -e $src_path ]] || die "Error: $1 is not in the password store."
+
+	mkdir -p -v "${dst_path%/*}"
+	[[ -d $src_path || -d $dst_path || $dst_path == */ ]] || dst_path="${dst_path}.gpg"
+
+	local interactive="-i"
+	[[ ! -t 0 || $force -eq 1 ]] && interactive="-f"
+
+	set_git "$dst_path"
+	ln -s $interactive -r -v "$src_path" "$dst_path" || exit 1
+	git_add_file "$dst_path" "Link ${1} to ${2}."
+}
+
 cmd_git() {
 	set_git "$PREFIX/"
 	if [[ $1 == "init" ]]; then
@@ -715,6 +750,7 @@ case "$1" in
 	delete|rm|remove) shift;	cmd_delete "$@" ;;
 	rename|mv) shift;		cmd_copy_move "move" "$@" ;;
 	copy|cp) shift;			cmd_copy_move "copy" "$@" ;;
+	link|ln) shift;			cmd_link "$@" ;;
 	git) shift;			cmd_git "$@" ;;
 	*)				cmd_extension_or_show "$@" ;;
 esac
--
2.39.0



More information about the Password-Store mailing list