Repository: borgbackup/borg

Issue:
Check borg --version on remote 
## Have you checked borgbackup docs, FAQ, and open GitHub issues?
YES - I hope I didn't miss the relevant information.

## Is this a BUG / ISSUE report or a QUESTION?
Question

## System information. For client/server mode, post info for both machines.
client: Linux Mint 21.2
server: synology NAS

#### Your borg version (borg -V).
client: 1.2.4
server: 1.2.6 

## Describe the problem you're observing.
Using a shell script to run daily backup, I thought that providing the borg --version for client and remote could be useful information for my logs. 

To get the version of the client, the following command did the job:
`borg --version  `

Now, I (wrongly?) tried the following to get the version of the remote backup server:  
`borg --version --remote-path='/usr/local/bin/borg' ssh://admin@192.168.0.5 \   `

I expected to get the borg version on the remote computer, here. 
However, this did not work, instead, somewhat unexpected (to me :-) )  the version of the client is reported, again.

In order to get the remote borg version, instead, I used the following command:
`ssh admin@192.168.0.5 /usr/local/bin/borg --version`
i.e. ssh into the server and execute borg --version there. 

Here is my question: 
Is there a way to get the remote borg-version, using the borg syntax? Did I miss something? 

I believe it would be convenient, to get the remote borg version, when a remote server (ssh://...) is provided at the same time. 
 




Discussion:
Good idea, that is not implemented yet.

Internally, borg client and server exchange some version information, but there is no special borg command to display the remote borg version.

Resolving patch:
diff --git a/src/borg/archiver.py b/src/borg/archiver.py
--- a/src/borg/archiver.py
+++ b/src/borg/archiver.py
@@ -288,6 +288,17 @@ def do_serve(self, args):
             storage_quota=args.storage_quota,
         ).serve()
 
+    def do_version(self, args):
+        """Display the borg client / borg server version"""
+        from borg.version import parse_version, format_version
+        client_version = parse_version(__version__)
+        if args.location.proto == 'ssh':
+            with RemoteRepository(args.location.omit_archive(), lock=False, args=args) as repository:
+                server_version = repository.server_version
+        else:
+            server_version = client_version
+        print(f"{format_version(client_version)} / {format_version(server_version)}")
+
     @with_repository(create=True, exclusive=True, manifest=False)
     def do_init(self, args, repository):
         """Initialize an empty repository"""
@@ -4134,6 +4145,40 @@ def define_borg_mount(parser):
                                help='format output as JSON')
         define_archive_filters_group(subparser)
 
+        # borg version
+        version_epilog = process_epilog("""
+        This command displays the borg client version / borg server version.
+
+        If a local repo is given, the client code directly accesses the repository,
+        thus we show the client version also as the server version.
+
+        If a remote repo is given (e.g. ssh:), the remote borg is queried and
+        its version is displayed as the server version.
+
+        Examples::
+
+            # local repo (client uses 1.4.0 alpha version)
+            $ borg version /mnt/backup
+            1.4.0a / 1.4.0a
+
+            # remote repo (client uses 1.4.0 alpha, server uses 1.2.7 release)
+            $ borg version ssh://borg@borgbackup:repo
+            1.4.0a / 1.2.7
+
+        Due to the version tuple format used in borg client/server negotiation, only
+        a simplified version is displayed (as provided by borg.version.format_version).
+
+        There is also borg --version to display a potentially more precise client version.
+        """)
+        subparser = subparsers.add_parser('version', parents=[common_parser], add_help=False,
+                                          description=self.do_version.__doc__, epilog=version_epilog,
+                                          formatter_class=argparse.RawDescriptionHelpFormatter,
+                                          help='display borg client version / borg server version')
+        subparser.set_defaults(func=self.do_version)
+        subparser.add_argument('location', metavar='REPOSITORY', nargs='?', default='',
+                               type=location_validator(archive=False),
+                               help='repository (used to determine client/server situation)')
+
         # borg init
         init_epilog = process_epilog("""
         This command initializes an empty repository. A repository is a filesystem


Test patch: