elisp: Truenames

 
 24.6.3 Truenames
 ----------------
 
 The “truename” of a file is the name that you get by following symbolic
 links at all levels until none remain, then simplifying away ‘.’ and
 ‘..’ appearing as name components.  This results in a sort of canonical
 name for the file.  A file does not always have a unique truename; the
 number of distinct truenames a file has is equal to the number of hard
 links to the file.  However, truenames are useful because they eliminate
 symbolic links as a cause of name variation.
 
  -- Function: file-truename filename
      This function returns the truename of the file FILENAME.  If the
      argument is not an absolute file name, this function first expands
      it against ‘default-directory’.
 
      This function does not expand environment variables.  Only
      ‘substitute-in-file-name’ does that.  SeeDefinition of
      substitute-in-file-name.
 
      If you may need to follow symbolic links preceding ‘..’ appearing
      as a name component, call ‘file-truename’ without prior direct or
      indirect calls to ‘expand-file-name’.  Otherwise, the file name
      component immediately preceding ‘..’ will be simplified away before
      ‘file-truename’ is called.  To eliminate the need for a call to
      ‘expand-file-name’, ‘file-truename’ handles ‘~’ in the same way
      that ‘expand-file-name’ does.  SeeFunctions that Expand
      Filenames File Name Expansion.
 
  -- Function: file-chase-links filename &optional limit
      This function follows symbolic links, starting with FILENAME, until
      it finds a file name which is not the name of a symbolic link.
      Then it returns that file name.  This function does _not_ follow
      symbolic links at the level of parent directories.
 
      If you specify a number for LIMIT, then after chasing through that
      many links, the function just returns what it has even if that is
      still a symbolic link.
 
    To illustrate the difference between ‘file-chase-links’ and
 ‘file-truename’, suppose that ‘/usr/foo’ is a symbolic link to the
 directory ‘/home/foo’, and ‘/home/foo/hello’ is an ordinary file (or at
 least, not a symbolic link) or nonexistent.  Then we would have:
 
      (file-chase-links "/usr/foo/hello")
           ;; This does not follow the links in the parent directories.
           ⇒ "/usr/foo/hello"
      (file-truename "/usr/foo/hello")
           ;; Assuming that ‘/home’ is not a symbolic link.
           ⇒ "/home/foo/hello"
 
  -- Function: file-equal-p file1 file2
      This function returns ‘t’ if the files FILE1 and FILE2 name the
      same file.  This is similar to comparing their truenames, except
      that remote file names are also handled in an appropriate manner.
      If FILE1 or FILE2 does not exist, the return value is unspecified.
 
  -- Function: file-in-directory-p file dir
      This function returns ‘t’ if FILE is a file in directory DIR, or in
      a subdirectory of DIR.  It also returns ‘t’ if FILE and DIR are the
      same directory.  It compares the truenames of the two directories.
      If DIR does not name an existing directory, the return value is
      ‘nil’.
 
  -- Function: vc-responsible-backend file
      This function determines the responsible VC backend of the given
      FILE.  For example, if ‘emacs.c’ is a file tracked by Git,
      ‘(vc-responsible-backend "emacs.c")’ returns ‘Git’.  Note that if
      FILE is a symbolic link, ‘vc-responsible-backend’ will not resolve
      it—the backend of the symbolic link file itself is reported.  To
      get the backend VC of the file to which FILE refers, wrap FILE with
      a symbolic link resolving function such as ‘file-chase-links’:
 
           (vc-responsible-backend (file-chase-links "emacs.c"))