External Tramp methods can be used in multi-hops
* doc/misc/tramp.texi (External methods): Mention, how external methods are used for multi-hops. (Ad-hoc multi-hops): Change requirement of method. * doc/misc/trampver.texi: * lisp/net/trampver.el: Change version to "2.8.2-pre". * etc/NEWS: External Tramp methods can be used in multi-hops. Presentational fixes and improvements. * lisp/net/tramp-sh.el (tramp-sh-handle-copy-directory): Check for `tramp-method-out-of-band-p' explicitly. Don't flush directory properties. (tramp-method-out-of-band-p): There shouldn't be a multi-hop. * lisp/net/tramp-smb.el (tramp-smb-handle-copy-directory): Don't flush directory properties. * lisp/net/tramp.el (tramp-methods): Adapt docstring. (tramp-barf-if-file-missing) (with-parsed-tramp-file-name): Adapt debug spec. (tramp-skeleton-copy-directory): Flush directory properties. (tramp-add-hops): Check for `tramp-login-args' property.
This commit is contained in:
@@ -1132,9 +1132,11 @@ an external transfer program.
|
||||
External methods save on the overhead of encoding and decoding of
|
||||
inline methods.
|
||||
|
||||
@vindex tramp-copy-size-limit
|
||||
Since external methods have the overhead of opening a new channel,
|
||||
files smaller than @code{tramp-copy-size-limit} still use inline
|
||||
methods.
|
||||
methods. If an external method is used inside a multi-hop connection
|
||||
(@pxref{Multi-hops}), its inherent inline method is used as well.
|
||||
|
||||
@table @asis
|
||||
@cindex method @option{rcp}
|
||||
@@ -3891,7 +3893,7 @@ proxy @samp{bird@@bastion} to a remote file on @samp{you@@remotehost}:
|
||||
ssh@value{postfixhop}you@@remotehost@value{postfix}/path @key{RET}}
|
||||
@end example
|
||||
|
||||
Each involved method must be an inline method (@pxref{Inline methods}).
|
||||
Each involved method must be handled by @value{tramp}'s @code{tramp-sh} backend.
|
||||
|
||||
@value{tramp} adds the ad-hoc definitions as an ephemeral record to
|
||||
@code{tramp-default-proxies-alist}, which are available for reuse
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
@c In the Tramp GIT, the version number and the bug report address
|
||||
@c are auto-frobbed from configure.ac.
|
||||
@set trampver 2.8.1
|
||||
@set trampver 2.8.2-pre
|
||||
@set trampurl https://www.gnu.org/software/tramp/
|
||||
@set tramp-bug-report-address tramp-devel@@gnu.org
|
||||
@set emacsver 28.1
|
||||
|
||||
37
etc/NEWS
37
etc/NEWS
@@ -471,7 +471,7 @@ either resize the frame and change the fullscreen status accordingly or
|
||||
keep the frame size unchanged. The value t means to first reset the
|
||||
fullscreen status and then resize the frame.
|
||||
|
||||
*** New commands to set frame size and position in one compound step.
|
||||
*** New functions to set frame size and position in one compound step.
|
||||
'set-frame-size-and-position' sets the new size and position of a frame
|
||||
in one compound step. Both, size and position, can be specified as with
|
||||
the corresponding frame parameters 'width', 'height', 'left' and 'top'.
|
||||
@@ -493,7 +493,7 @@ an error when a frame of that name already exists.
|
||||
The frame parameter 'cloned-from' is set to the frame from which the new
|
||||
frame is cloned using the command 'clone-frame'.
|
||||
|
||||
The frame parameter 'undeleted is set to t when a frame is undeleted
|
||||
The frame parameter 'undeleted' is set to t when a frame is undeleted
|
||||
using the command 'undelete-frame'.
|
||||
|
||||
These are useful if you need to detect a cloned frame or undeleted frame
|
||||
@@ -1057,11 +1057,11 @@ The new variable 'forward-comment-function' is set to the new function
|
||||
'treesit-forward-comment' if a major mode defines the thing 'comment'.
|
||||
|
||||
+++
|
||||
*** New function 'treesit-query-eagerly-compiled-p'
|
||||
*** New function 'treesit-query-eagerly-compiled-p'.
|
||||
This function returns non-nil if a query was eagerly compiled.
|
||||
|
||||
+++
|
||||
*** New function 'treesit-query-source'
|
||||
*** New function 'treesit-query-source'.
|
||||
This function returns the string or sexp source query of a compiled query.
|
||||
|
||||
+++
|
||||
@@ -1153,8 +1153,9 @@ convention. Also, the ':match?' predicate can now take the regexp as
|
||||
either the first or second argument, so it works with both tree-sitter
|
||||
convention (regexp arg second) and Emacs convention (regexp arg first).
|
||||
|
||||
** Track changes
|
||||
|
||||
+++
|
||||
** Track-changes
|
||||
*** New variable 'track-changes-undo-only' to distinguish undo changes.
|
||||
|
||||
** Hideshow
|
||||
@@ -1170,7 +1171,7 @@ blocks.
|
||||
This command hides or shows all the blocks in the current buffer.
|
||||
|
||||
---
|
||||
*** 'hs-hide-level' no longer hide all the blocks in the current buffer.
|
||||
*** 'hs-hide-level' no longer hides all the blocks in the current buffer.
|
||||
If 'hs-hide-level' was not inside a code block it would hide all the
|
||||
blocks in the buffer like 'hs-hide-all'. Now it should only hide all
|
||||
the second level blocks.
|
||||
@@ -1229,7 +1230,6 @@ buffer-local variables 'hs-block-start-regexp', 'hs-c-start-regexp',
|
||||
*** 'hs-hide-level' and 'hs-cycle' can now hide comments too.
|
||||
This is controlled by 'hs-hide-comments-when-hiding-all'.
|
||||
|
||||
|
||||
** C-ts mode
|
||||
|
||||
+++
|
||||
@@ -1644,7 +1644,6 @@ is the default.
|
||||
This user option is in sympathy with recentf, and savehist autosave
|
||||
timers.
|
||||
|
||||
|
||||
** Savehist
|
||||
|
||||
---
|
||||
@@ -2014,7 +2013,7 @@ for docstrings where symbols 'nil' and 't' are in quotes.
|
||||
In most cases, having it enabled leads to a large amount of false
|
||||
positives.
|
||||
|
||||
*** New file-local variable 'lisp-indent-local-overrides'
|
||||
*** New file-local variable 'lisp-indent-local-overrides'.
|
||||
This variable can be used to locally override the indent specification
|
||||
of symbols.
|
||||
|
||||
@@ -2083,6 +2082,10 @@ connections after you close remote-file buffers without having to either
|
||||
cherry-pick via 'tramp-cleanup-connection' or clear them all via
|
||||
'tramp-cleanup-all-connections'.
|
||||
|
||||
+++
|
||||
*** External methods can now be used in multi-hop connections.
|
||||
This is implemented for 'tramp-sh' methods, like "/scp:user@host|sudo::".
|
||||
|
||||
+++
|
||||
*** New command 'tramp-dired-find-file-with-sudo'.
|
||||
This command, bound to '@' in Dired, visits the file or directory on the
|
||||
@@ -2463,7 +2466,7 @@ appearance of the list can be customized with the new faces
|
||||
|
||||
+++
|
||||
*** Printing root branch logs has moved to 'C-x v b L'.
|
||||
Previously the command to print the root log for a branch was bound to
|
||||
Previously, the command to print the root log for a branch was bound to
|
||||
'C-x v b l'. It has now been renamed from 'vc-print-branch-log' to
|
||||
'vc-print-root-branch-log', and bound to 'C-x v b L'. This is more
|
||||
consistent with the rest of the 'C-x v' keymap, and makes room for a new
|
||||
@@ -2676,7 +2679,7 @@ bindings:
|
||||
*** New display of outgoing revisions count in VC Directory.
|
||||
If there are outgoing revisions, VC Directory now includes a count of
|
||||
how many in its headers, to remind you to push them.
|
||||
You can disable this by customizing vc-dir-show-outgoing-count to nil.
|
||||
You can disable this by customizing 'vc-dir-show-outgoing-count' to nil.
|
||||
|
||||
+++
|
||||
*** New user option 'vc-async-checkin' to enable async checkin operations.
|
||||
@@ -3312,7 +3315,7 @@ the source, or to 'antlr-v3' otherwise.
|
||||
|
||||
*** New command 'antlr-v4-mode' is a derived mode of 'antlr-mode'.
|
||||
It sets 'antlr-tool-version' to value 'antlr-v4', and is automatically
|
||||
used for files with extension "g4".
|
||||
used for files with extension ".g4".
|
||||
|
||||
*** The variable 'antlr-language' is now used more generally.
|
||||
The variable has a symbol as value which determines which of the
|
||||
@@ -3325,8 +3328,8 @@ ObjC, Python and Ruby, additional to Java and Cpp.
|
||||
|
||||
*** New user option 'antlr-run-tool-on-buffer-file'.
|
||||
Command 'antlr-run-tool' now usually runs on the file for the current
|
||||
buffer. Customize this user option to have value ' nil' to get the
|
||||
previous behavior back.
|
||||
buffer. Customize this user option to nil to get the previous behavior
|
||||
back.
|
||||
|
||||
** Hi Lock
|
||||
|
||||
@@ -3497,8 +3500,8 @@ separator, are also supported.
|
||||
|
||||
---
|
||||
** The experimental variable 'binary-as-unsigned' has been removed.
|
||||
Instead of (let ((binary-as-unsigned t)) (format "%x" N)) you can use
|
||||
(format "%x" (logand N MASK)) where MASK is for the desired word size,
|
||||
Instead of '(let ((binary-as-unsigned t)) (format "%x" N))' you can use
|
||||
'(format "%x" (logand N MASK))' where MASK is for the desired word size,
|
||||
e.g., #x3fffffffffffffff for typical Emacs fixnums.
|
||||
|
||||
+++
|
||||
@@ -3862,7 +3865,7 @@ called on progress steps, and DONE-CALLBACK, called when the progress
|
||||
reporter is done. See the 'make-progress-reporter' docstring for a full
|
||||
specification of these new optional arguments.
|
||||
|
||||
** Add binary format specifications '%b' and '%B'.
|
||||
** Binary format specifications '%b' and '%B' added.
|
||||
These produce the binary representation of a number.
|
||||
'%#b' and '%#B' prefix the bits with '0b' and '0B', respectively.
|
||||
|
||||
|
||||
@@ -2098,66 +2098,67 @@ ID-FORMAT valid values are `string' and `integer'."
|
||||
"Like `copy-directory' for Tramp files."
|
||||
(tramp-skeleton-copy-directory
|
||||
dirname newname keep-date parents copy-contents
|
||||
(let ((t1 (tramp-tramp-file-p dirname))
|
||||
(t2 (tramp-tramp-file-p newname))
|
||||
target)
|
||||
(with-parsed-tramp-file-name (if t1 dirname newname) nil
|
||||
(cond
|
||||
((and copy-directory-create-symlink
|
||||
(setq target (file-symlink-p dirname))
|
||||
(tramp-equal-remote dirname newname))
|
||||
(make-symbolic-link
|
||||
target
|
||||
(if (directory-name-p newname)
|
||||
(concat newname (file-name-nondirectory dirname)) newname)
|
||||
t))
|
||||
(let* ((v1 (and (tramp-tramp-file-p dirname)
|
||||
(tramp-dissect-file-name dirname)))
|
||||
(v2 (and (tramp-tramp-file-p newname)
|
||||
(tramp-dissect-file-name newname)))
|
||||
(v (or v1 v2))
|
||||
target)
|
||||
(cond
|
||||
((and copy-directory-create-symlink
|
||||
(setq target (file-symlink-p dirname))
|
||||
(tramp-equal-remote dirname newname))
|
||||
(make-symbolic-link
|
||||
target
|
||||
(if (directory-name-p newname)
|
||||
(concat newname (file-name-nondirectory dirname)) newname)
|
||||
t))
|
||||
|
||||
;; Shortcut: if method, host, user are the same for both
|
||||
;; files, we invoke `cp' on the remote host directly.
|
||||
((and (not copy-contents)
|
||||
(tramp-equal-remote dirname newname))
|
||||
(when (and (file-directory-p newname)
|
||||
(not (directory-name-p newname)))
|
||||
(tramp-error v 'file-already-exists newname))
|
||||
(setq dirname (directory-file-name (expand-file-name dirname))
|
||||
newname (directory-file-name (expand-file-name newname)))
|
||||
(tramp-do-copy-or-rename-file-directly
|
||||
'copy dirname newname
|
||||
'ok-if-already-exists keep-date 'preserve-uid-gid))
|
||||
;; Shortcut: if method, host, user are the same for both files,
|
||||
;; we invoke `cp' on the remote host directly.
|
||||
((and (not copy-contents)
|
||||
(tramp-equal-remote dirname newname))
|
||||
(when (and (file-directory-p newname)
|
||||
(not (directory-name-p newname)))
|
||||
(tramp-error v 'file-already-exists newname))
|
||||
(setq dirname (directory-file-name (expand-file-name dirname))
|
||||
newname (directory-file-name (expand-file-name newname)))
|
||||
(tramp-do-copy-or-rename-file-directly
|
||||
'copy dirname newname
|
||||
'ok-if-already-exists keep-date 'preserve-uid-gid))
|
||||
|
||||
;; scp or rsync DTRT.
|
||||
((and (not copy-contents)
|
||||
(tramp-get-method-parameter v 'tramp-copy-recursive)
|
||||
;; When DIRNAME and NEWNAME are remote, they must have
|
||||
;; the same method.
|
||||
(or (null t1) (null t2)
|
||||
(string-equal
|
||||
(tramp-file-name-method (tramp-dissect-file-name dirname))
|
||||
(tramp-file-name-method (tramp-dissect-file-name newname)))))
|
||||
(when (and (file-directory-p newname)
|
||||
(not (directory-name-p newname)))
|
||||
(tramp-error v 'file-already-exists newname))
|
||||
(setq dirname (directory-file-name (expand-file-name dirname))
|
||||
newname (directory-file-name (expand-file-name newname)))
|
||||
(when (and (file-directory-p newname)
|
||||
(not (string-equal (file-name-nondirectory dirname)
|
||||
(file-name-nondirectory newname))))
|
||||
(setq newname
|
||||
(expand-file-name (file-name-nondirectory dirname) newname)))
|
||||
(unless (file-directory-p (file-name-directory newname))
|
||||
(make-directory (file-name-directory newname) parents))
|
||||
(tramp-do-copy-or-rename-file-out-of-band
|
||||
'copy dirname newname 'ok-if-already-exists keep-date))
|
||||
;; scp or rsync DTRT.
|
||||
((and (not copy-contents)
|
||||
(tramp-get-method-parameter v 'tramp-copy-recursive)
|
||||
;; When DIRNAME and NEWNAME are remote, they must have
|
||||
;; the same method. None of them must be multi-hop.
|
||||
(or (and (null v1) (tramp-method-out-of-band-p v2 0))
|
||||
(and (null v2) (tramp-method-out-of-band-p v1 0))
|
||||
(and v1 v2
|
||||
(tramp-method-out-of-band-p v1 0)
|
||||
(tramp-method-out-of-band-p v2 0)
|
||||
(string-equal
|
||||
(tramp-file-name-method v1)
|
||||
(tramp-file-name-method v2)))))
|
||||
(when (and (file-directory-p newname)
|
||||
(not (directory-name-p newname)))
|
||||
(tramp-error v 'file-already-exists newname))
|
||||
(setq dirname (directory-file-name (expand-file-name dirname))
|
||||
newname (directory-file-name (expand-file-name newname)))
|
||||
(when (and (file-directory-p newname)
|
||||
(not (string-equal (file-name-nondirectory dirname)
|
||||
(file-name-nondirectory newname))))
|
||||
(setq newname
|
||||
(expand-file-name (file-name-nondirectory dirname) newname)))
|
||||
(unless (file-directory-p (file-name-directory newname))
|
||||
(make-directory (file-name-directory newname) parents))
|
||||
(tramp-do-copy-or-rename-file-out-of-band
|
||||
'copy dirname newname 'ok-if-already-exists keep-date))
|
||||
|
||||
;; We must do it file-wise.
|
||||
(t (tramp-run-real-handler
|
||||
#'copy-directory
|
||||
(list dirname newname keep-date parents copy-contents))))
|
||||
|
||||
;; NEWNAME has wrong cached values.
|
||||
(when t2
|
||||
(with-parsed-tramp-file-name (expand-file-name newname) nil
|
||||
(tramp-flush-file-properties v localname)))))))
|
||||
;; We must do it file-wise.
|
||||
(t (tramp-run-real-handler
|
||||
#'copy-directory
|
||||
(list dirname newname keep-date parents copy-contents)))))))
|
||||
|
||||
(defun tramp-sh-handle-rename-file
|
||||
(filename newname &optional ok-if-already-exists)
|
||||
@@ -5679,7 +5680,11 @@ raises an error."
|
||||
(and
|
||||
;; It shall be an out-of-band method.
|
||||
(tramp-get-method-parameter vec 'tramp-copy-program)
|
||||
;; There must be a size, otherwise the file doesn't exist.
|
||||
;; There shouldn't be a multi-hop.
|
||||
(or (not (tramp-multi-hop-p vec))
|
||||
(null (cdr (tramp-compute-multi-hops vec))))
|
||||
;; There must be a SIZE, otherwise the file doesn't exist. A zero
|
||||
;; SIZE is used for directories.
|
||||
(numberp size)
|
||||
;; Either the file size is large enough, or (in rare cases) there
|
||||
;; does not exist a remote encoding.
|
||||
|
||||
@@ -577,12 +577,7 @@ arguments to pass to the OPERATION."
|
||||
|
||||
;; Set the mode.
|
||||
(unless keep-date
|
||||
(set-file-modes newname (tramp-default-file-modes dirname)))
|
||||
|
||||
;; When newname did exist, we have wrong cached values.
|
||||
(when t2
|
||||
(with-parsed-tramp-file-name newname nil
|
||||
(tramp-flush-file-properties v localname))))
|
||||
(set-file-modes newname (tramp-default-file-modes dirname))))
|
||||
|
||||
;; We must do it file-wise.
|
||||
(t
|
||||
|
||||
@@ -296,9 +296,8 @@ pair of the form (KEY VALUE). The following KEYs are defined:
|
||||
- \"%a\" adds the pseudo-terminal allocation argument \"-t\" in
|
||||
asynchronous processes, if the connection type is not `pipe'.
|
||||
|
||||
The existence of `tramp-login-args', combined with the
|
||||
absence of `tramp-copy-args', is an indication that the
|
||||
method is capable of multi-hops.
|
||||
The existence of `tramp-login-args' is an indication that the method
|
||||
is capable of multi-hops.
|
||||
|
||||
* `tramp-async-args'
|
||||
When an asynchronous process is started, we know already that
|
||||
@@ -2137,7 +2136,7 @@ of `current-buffer'."
|
||||
"Execute BODY and return the result.
|
||||
In case of an error, raise a `file-missing' error if FILENAME
|
||||
does not exist, otherwise propagate the error."
|
||||
(declare (indent 2) (debug (tramp-file-name-p form &rest body)))
|
||||
(declare (indent 2) (debug t))
|
||||
(let ((err (make-symbol "err")))
|
||||
`(condition-case ,err
|
||||
(let (signal-hook-function) ,@body)
|
||||
@@ -2176,7 +2175,7 @@ Remaining args are Lisp expressions to be evaluated (inside an implicit
|
||||
|
||||
If VAR is nil, then we bind `v' to the structure and `method', `user',
|
||||
`domain', `host', `port', `localname', `hop' to the components."
|
||||
(declare (indent 2) (debug (form symbolp &rest body)))
|
||||
(declare (indent 2) (debug t))
|
||||
(let ((bindings
|
||||
(mapcar
|
||||
(lambda (elem)
|
||||
@@ -3585,7 +3584,7 @@ User is always nil."
|
||||
;;; Skeleton macros for file name handler functions.
|
||||
|
||||
(defmacro tramp-skeleton-copy-directory
|
||||
(directory _newname &optional _keep-date _parents _copy-contents &rest body)
|
||||
(directory newname &optional _keep-date _parents _copy-contents &rest body)
|
||||
"Skeleton for `tramp-*-handle-copy-directory'.
|
||||
BODY is the backend specific code."
|
||||
(declare (indent 5) (debug t))
|
||||
@@ -3596,7 +3595,12 @@ BODY is the backend specific code."
|
||||
(unless (file-exists-p ,directory)
|
||||
(tramp-error
|
||||
(tramp-dissect-file-name ,directory) 'file-missing ,directory))
|
||||
,@body))
|
||||
,@body
|
||||
|
||||
;; NEWNAME has wrong cached values.
|
||||
(when (tramp-tramp-file-p ,newname)
|
||||
(with-parsed-tramp-file-name (expand-file-name ,newname) nil
|
||||
(tramp-flush-file-properties v localname)))))
|
||||
|
||||
(defmacro tramp-skeleton-delete-directory (directory recursive trash &rest body)
|
||||
"Skeleton for `tramp-*-handle-delete-directory'.
|
||||
@@ -5148,7 +5152,7 @@ Do not set it manually, it is used buffer-local in `tramp-get-lock-pid'.")
|
||||
"Whether the method of VEC is capable of multi-hops."
|
||||
(let ((tramp-verbose 0))
|
||||
(and (tramp-sh-file-name-handler-p vec)
|
||||
(not (tramp-get-method-parameter vec 'tramp-copy-program)))))
|
||||
(tramp-get-method-parameter vec 'tramp-login-args))))
|
||||
|
||||
(defun tramp-add-hops (vec)
|
||||
"Add ad-hoc proxy definitions to `tramp-default-proxies-alist'."
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
;; Maintainer: Michael Albinus <michael.albinus@gmx.de>
|
||||
;; Keywords: comm, processes
|
||||
;; Package: tramp
|
||||
;; Version: 2.8.1
|
||||
;; Version: 2.8.2-pre
|
||||
;; Package-Requires: ((emacs "28.1"))
|
||||
;; Package-Type: multi
|
||||
;; URL: https://www.gnu.org/software/tramp/
|
||||
@@ -40,7 +40,7 @@
|
||||
;; ./configure" to change them.
|
||||
|
||||
;;;###tramp-autoload
|
||||
(defconst tramp-version "2.8.1"
|
||||
(defconst tramp-version "2.8.2-pre"
|
||||
"This version of Tramp.")
|
||||
|
||||
;;;###tramp-autoload
|
||||
@@ -76,7 +76,7 @@
|
||||
;; Check for Emacs version.
|
||||
(let ((x (if (not (string-version-lessp emacs-version "28.1"))
|
||||
"ok"
|
||||
(format "Tramp 2.8.1 is not fit for %s"
|
||||
(format "Tramp 2.8.2-pre is not fit for %s"
|
||||
(replace-regexp-in-string "\n" "" (emacs-version))))))
|
||||
(unless (string-equal "ok" x) (error "%s" x)))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user