internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: borgbackup/borg

Issue:
macOS finder hides mountpoint directory name
```
borg mount repo mnt
```
Instead of the original directory name (`mnt`) of the mountpoint, it displays "macFUSE Volume 0 (Python)":

![image](https://github.com/borgbackup/borg/assets/356103/32d0c13d-1f02-40cf-8cdc-66b9f59c404a)



Discussion:
OK, found it, we need to give `volname=...` mount option to macFUSE to set this.

So, set this to `mountpoint_directory  (borgfs mounted)` (it also displays a **eject** symbol to the right of that) or better just `mountpoint_directory`?

Resolving patch:
diff --git a/src/borg/fuse.py b/src/borg/fuse.py
--- a/src/borg/fuse.py
+++ b/src/borg/fuse.py
@@ -40,6 +40,7 @@ def async_wrapper(fn):
 from .item import Item
 from .lrucache import LRUCache
 from .platform import uid2user, gid2group
+from .platformflags import is_darwin
 from .remote import RemoteRepository
 
 
@@ -522,6 +523,13 @@ def pop_option(options, key, present, not_present, wanted_type, int_base=0):
         options = ['fsname=borgfs', 'ro', 'default_permissions']
         if mount_options:
             options.extend(mount_options.split(','))
+        if is_darwin:
+            # macFUSE supports a volname mount option to give what finder displays on desktop / in directory list.
+            volname = pop_option(options, 'volname', '', '', str)
+            # if the user did not specify it, we make something up,
+            # because otherwise it would be "macFUSE Volume 0 (Python)", #7690.
+            volname = volname or f"{os.path.basename(mountpoint)} (borgfs)"
+            options.append(f"volname={volname}")
         ignore_permissions = pop_option(options, 'ignore_permissions', True, False, bool)
         if ignore_permissions:
             # in case users have a use-case that requires NOT giving "default_permissions",


Test patch:
Repository: borgbackup/borg

Issue:
macOS finder hides mountpoint directory name
```
borg mount repo mnt
```
Instead of the original directory name (`mnt`) of the mountpoint, it displays "macFUSE Volume 0 (Python)":

![image](https://github.com/borgbackup/borg/assets/356103/32d0c13d-1f02-40cf-8cdc-66b9f59c404a)



Discussion:
OK, found it, we need to give `volname=...` mount option to macFUSE to set this.

So, set this to `mountpoint_directory  (borgfs mounted)` (it also displays a **eject** symbol to the right of that) or better just `mountpoint_directory`?

Resolving patch:
diff --git a/src/borg/fuse.py b/src/borg/fuse.py
--- a/src/borg/fuse.py
+++ b/src/borg/fuse.py
@@ -44,6 +44,7 @@ def async_wrapper(fn):
 from .helpers.lrucache import LRUCache
 from .item import Item
 from .platform import uid2user, gid2group
+from .platformflags import is_darwin
 from .remote import RemoteRepository
 
 
@@ -513,6 +514,13 @@ def pop_option(options, key, present, not_present, wanted_type, int_base=0):
         options = ["fsname=borgfs", "ro", "default_permissions"]
         if mount_options:
             options.extend(mount_options.split(","))
+        if is_darwin:
+            # macFUSE supports a volname mount option to give what finder displays on desktop / in directory list.
+            volname = pop_option(options, "volname", "", "", str)
+            # if the user did not specify it, we make something up,
+            # because otherwise it would be "macFUSE Volume 0 (Python)", #7690.
+            volname = volname or f"{os.path.basename(mountpoint)} (borgfs)"
+            options.append(f"volname={volname}")
         ignore_permissions = pop_option(options, "ignore_permissions", True, False, bool)
         if ignore_permissions:
             # in case users have a use-case that requires NOT giving "default_permissions",


Test patch:
Repository: borgbackup/borg

Issue:
manifest: move item_keys to config dict
borg2 / master only.

From the docs:

`config` is a general-purpose location for additional metadata. All versions
of Borg preserve its contents (it may have been a better place for `item_keys`,
which is not preserved by unaware Borg versions, releases predating 1.0.4).


Discussion:

Resolving patch:
diff --git a/src/borg/manifest.py b/src/borg/manifest.py
--- a/src/borg/manifest.py
+++ b/src/borg/manifest.py
@@ -264,7 +264,9 @@ def load(cls, repository, operations, key=None, force_tam_not_required=False, *,
         manifest.timestamp = m.get("timestamp")
         manifest.config = m.config
         # valid item keys are whatever is known in the repo or every key we know
-        manifest.item_keys = ITEM_KEYS | frozenset(m.get("item_keys", []))
+        manifest.item_keys = ITEM_KEYS
+        manifest.item_keys |= frozenset(m.config.get("item_keys", []))  # new location of item_keys since borg2
+        manifest.item_keys |= frozenset(m.get("item_keys", []))  # legacy: borg 1.x: item_keys not in config yet
 
         if manifest.tam_verified:
             manifest_required = manifest.config.get("tam_required", False)
@@ -321,12 +323,12 @@ def write(self):
         assert len(self.archives) <= MAX_ARCHIVES
         assert all(len(name) <= 255 for name in self.archives)
         assert len(self.item_keys) <= 100
+        self.config["item_keys"] = tuple(sorted(self.item_keys))
         manifest = ManifestItem(
-            version=1,
+            version=2,
             archives=StableDict(self.archives.get_raw_dict()),
             timestamp=self.timestamp,
             config=StableDict(self.config),
-            item_keys=tuple(sorted(self.item_keys)),
         )
         self.tam_verified = True
         data = self.key.pack_and_authenticate_metadata(manifest.as_dict())
diff --git a/src/borg/testsuite/archiver/debug_cmds.py b/src/borg/testsuite/archiver/debug_cmds.py
--- a/src/borg/testsuite/archiver/debug_cmds.py
+++ b/src/borg/testsuite/archiver/debug_cmds.py
@@ -133,7 +133,8 @@ def test_debug_dump_manifest(self):
             result = json.load(f)
         assert "archives" in result
         assert "config" in result
-        assert "item_keys" in result
+        assert "item_keys" in result["config"]
+        assert frozenset(result["config"]["item_keys"]) == ITEM_KEYS
         assert "timestamp" in result
         assert "version" in result
 


Test patch:
Repository: borgbackup/borg

Issue:
check [--repair]: check/improve logging for archive-TAM issues
Due to the security issue, I needed to release 1.2.6 quite quickly after 1.2.5.

Maybe the logging is not perfect yet:

`borg check` should be more clear about when archives are to be deleted due to missing-TAM or TAM-invalid issues.



Discussion:

Resolving patch:
diff --git a/src/borg/archive.py b/src/borg/archive.py
--- a/src/borg/archive.py
+++ b/src/borg/archive.py
@@ -1820,13 +1820,17 @@ def valid_archive(obj):
                 # are likely looking at an archive item here, also check the TAM authentication:
                 try:
                     archive, verified, _ = self.key.unpack_and_verify_archive(data, force_tam_not_required=False)
-                except IntegrityError:
+                except IntegrityError as integrity_error:
                     # TAM issues - do not accept this archive!
                     # either somebody is trying to attack us with a fake archive data or
                     # we have an ancient archive made before TAM was a thing (borg < 1.0.9) **and** this repo
                     # was not correctly upgraded to borg 1.2.5 (see advisory at top of the changelog).
                     # borg can't tell the difference, so it has to assume this archive might be an attack
                     # and drops this archive.
+                    name = archive.get(b'name', b'<unknown>').decode('ascii', 'replace')
+                    logger.error('Archive TAM authentication issue for archive %s: %s', name, integrity_error)
+                    logger.error('This archive will *not* be added to the rebuilt manifest! It will be deleted.')
+                    self.error_found = True
                     continue
                 # note: if we get here and verified is False, a TAM is not required.
                 archive = ArchiveItem(internal_dict=archive)
@@ -2071,6 +2075,7 @@ def valid_item(obj):
                     # when upgrading to borg 1.2.5, users are expected to TAM-authenticate all archives they
                     # trust, so there shouldn't be any without TAM.
                     logger.error('Archive TAM authentication issue for archive %s: %s', info.name, integrity_error)
+                    logger.error('This archive will be *removed* from the manifest! It will be deleted.')
                     self.error_found = True
                     del self.manifest.archives[info.name]
                     continue


Test patch:
Repository: borgbackup/borg

Issue:
check [--repair]: check/improve logging for archive-TAM issues
Due to the security issue, I needed to release 1.2.6 quite quickly after 1.2.5.

Maybe the logging is not perfect yet:

`borg check` should be more clear about when archives are to be deleted due to missing-TAM or TAM-invalid issues.



Discussion:

Resolving patch:
diff --git a/src/borg/archive.py b/src/borg/archive.py
--- a/src/borg/archive.py
+++ b/src/borg/archive.py
@@ -1999,13 +1999,17 @@ def valid_archive(obj):
                 # are likely looking at an archive item here, also check the TAM authentication:
                 try:
                     archive, verified, _ = self.key.unpack_and_verify_archive(data, force_tam_not_required=False)
-                except IntegrityError:
+                except IntegrityError as integrity_error:
                     # TAM issues - do not accept this archive!
                     # either somebody is trying to attack us with a fake archive data or
                     # we have an ancient archive made before TAM was a thing (borg < 1.0.9) **and** this repo
                     # was not correctly upgraded to borg 1.2.5 (see advisory at top of the changelog).
                     # borg can't tell the difference, so it has to assume this archive might be an attack
                     # and drops this archive.
+                    name = archive.get(b"name", b"<unknown>").decode("ascii", "replace")
+                    logger.error("Archive TAM authentication issue for archive %s: %s", name, integrity_error)
+                    logger.error("This archive will *not* be added to the rebuilt manifest! It will be deleted.")
+                    self.error_found = True
                     continue
                 # note: if we get here and verified is False, a TAM is not required.
                 archive = ArchiveItem(internal_dict=archive)
@@ -2271,6 +2275,7 @@ def valid_item(obj):
                     # when upgrading to borg 1.2.5, users are expected to TAM-authenticate all archives they
                     # trust, so there shouldn't be any without TAM.
                     logger.error("Archive TAM authentication issue for archive %s: %s", info.name, integrity_error)
+                    logger.error("This archive will be *removed* from the manifest! It will be deleted.")
                     self.error_found = True
                     del self.manifest.archives[info.name]
                     continue


Test patch:
Repository: borgbackup/borg

Issue:
test next msgpack release
looks like msgpack 1.0.6 or maybe even 1.1.0 is around the corner.

wait for it, it might enable python 3.12 support for us.

https://github.com/msgpack/msgpack-python

https://pypi.org/project/msgpack/#history


Discussion:
borg seems to work fine with msgpack 1.0.6rc1.

so guess I'll just allow msgpack 1.0.6 now, assuming there won't be regressions after rc1.
if there were, our CI testing would find them quickly after that is released on pypi.


Resolving patch:
diff --git a/src/borg/helpers/msgpack.py b/src/borg/helpers/msgpack.py
--- a/src/borg/helpers/msgpack.py
+++ b/src/borg/helpers/msgpack.py
@@ -209,7 +209,7 @@ def is_supported_msgpack():
 
     if msgpack.version in []:  # < add bad releases here to deny list
         return False
-    return (1, 0, 3) <= msgpack.version < (1, 0, 7)
+    return (1, 0, 3) <= msgpack.version <= (1, 0, 6)
 
 
 def get_limited_unpacker(kind):
diff --git a/src/borg/testsuite/helpers.py b/src/borg/testsuite/helpers.py
--- a/src/borg/testsuite/helpers.py
+++ b/src/borg/testsuite/helpers.py
@@ -908,7 +908,22 @@ def test_parse_file_size_invalid(string):
         parse_file_size(string)
 
 
-@pytest.mark.skipif(is_cygwin, reason="ignore slow msgpack on cygwin")
+def expected_py_mp_slow_combination():
+    """do we expect msgpack to be slow in this environment?"""
+    # we need to import upstream msgpack package here, not helpers.msgpack:
+    import msgpack
+
+    # msgpack is slow on cygwin
+    if is_cygwin:
+        return True
+    # msgpack < 1.0.6 did not have py312 wheels
+    if sys.version_info[:2] == (3, 12) and msgpack.version < (1, 0, 6):
+        return True
+    # otherwise we expect msgpack to be fast!
+    return False
+
+
+@pytest.mark.skipif(expected_py_mp_slow_combination(), reason="ignore expected slow msgpack")
 def test_is_slow_msgpack():
     # we need to import upstream msgpack package here, not helpers.msgpack:
     import msgpack


Test patch:
Repository: borgbackup/borg

Issue:
borg-linuxold64 list: error: argument --sort-by: Invalid sort key: archive
Hello!

## Is this a BUG / ISSUE report or a QUESTION?

Might be a BUG

#### Your borg version (borg -V).

Borg v1.2.6 

#### Can you reproduce the problem?

Using '--sort-by="archive"' with borg list is rejected (syntax error).

Using '--sort-by="name"' with borg list works fine

---

borg list help says:

> Keys available only when listing archives in a repository:
>- archive: archive name interpreted as text (might be missing non-text characters, see barchive)
>- name: alias of "archive"

Because "name" is an alias or "archive", '--sort-by="archive"' should be accepted.

---

But, what is the official/recommended way to display/filter/glob archive name?

"name" or "archive"?

Have a great evening. :)


Discussion:
The code used for `--sort-by` in `Archives.list` currently only supports the `ArchiveInfo` attribute names:

name, id, ts

There is no support for aliases there.

`parseformat.SortBySpec` does a bit of preprocessing, so one can give timestamp instead of ts.

Could be extended to support the `archive` as alias of `name`.
> There is no support for aliases there.

Understood.

Doc is right (as always) but it may seem legit to expect "alias" to work with "borg list".

Thank you for your answer!
Maybe someone searching for an easy contribution can make a PR for this, see my hints above.

Resolving patch:
diff --git a/src/borg/helpers/manifest.py b/src/borg/helpers/manifest.py
--- a/src/borg/helpers/manifest.py
+++ b/src/borg/helpers/manifest.py
@@ -28,7 +28,8 @@ class MandatoryFeatureUnsupported(Error):
 
 ArchiveInfo = namedtuple('ArchiveInfo', 'name id ts')
 
-AI_HUMAN_SORT_KEYS = ['timestamp'] + list(ArchiveInfo._fields)
+# timestamp is a replacement for ts, archive is an alias for name (see SortBySpec)
+AI_HUMAN_SORT_KEYS = ['timestamp', 'archive'] + list(ArchiveInfo._fields)
 AI_HUMAN_SORT_KEYS.remove('ts')
 
 
diff --git a/src/borg/helpers/parseformat.py b/src/borg/helpers/parseformat.py
--- a/src/borg/helpers/parseformat.py
+++ b/src/borg/helpers/parseformat.py
@@ -228,7 +228,7 @@ def SortBySpec(text):
     for token in text.split(','):
         if token not in AI_HUMAN_SORT_KEYS:
             raise argparse.ArgumentTypeError('Invalid sort key: %s' % token)
-    return text.replace('timestamp', 'ts')
+    return text.replace('timestamp', 'ts').replace('archive', 'name')
 
 
 def format_file_size(v, precision=2, sign=False, iec=False):


Test patch:
Repository: borgbackup/borg

Issue:
borg-linuxold64 list: error: argument --sort-by: Invalid sort key: archive
Hello!

## Is this a BUG / ISSUE report or a QUESTION?

Might be a BUG

#### Your borg version (borg -V).

Borg v1.2.6 

#### Can you reproduce the problem?

Using '--sort-by="archive"' with borg list is rejected (syntax error).

Using '--sort-by="name"' with borg list works fine

---

borg list help says:

> Keys available only when listing archives in a repository:
>- archive: archive name interpreted as text (might be missing non-text characters, see barchive)
>- name: alias of "archive"

Because "name" is an alias or "archive", '--sort-by="archive"' should be accepted.

---

But, what is the official/recommended way to display/filter/glob archive name?

"name" or "archive"?

Have a great evening. :)


Discussion:
The code used for `--sort-by` in `Archives.list` currently only supports the `ArchiveInfo` attribute names:

name, id, ts

There is no support for aliases there.

`parseformat.SortBySpec` does a bit of preprocessing, so one can give timestamp instead of ts.

Could be extended to support the `archive` as alias of `name`.
> There is no support for aliases there.

Understood.

Doc is right (as always) but it may seem legit to expect "alias" to work with "borg list".

Thank you for your answer!
Maybe someone searching for an easy contribution can make a PR for this, see my hints above.

Resolving patch:
diff --git a/src/borg/helpers/parseformat.py b/src/borg/helpers/parseformat.py
--- a/src/borg/helpers/parseformat.py
+++ b/src/borg/helpers/parseformat.py
@@ -290,7 +290,7 @@ def SortBySpec(text):
     for token in text.split(","):
         if token not in AI_HUMAN_SORT_KEYS:
             raise argparse.ArgumentTypeError("Invalid sort key: %s" % token)
-    return text.replace("timestamp", "ts")
+    return text.replace("timestamp", "ts").replace("archive", "name")
 
 
 def format_file_size(v, precision=2, sign=False, iec=False):
diff --git a/src/borg/manifest.py b/src/borg/manifest.py
--- a/src/borg/manifest.py
+++ b/src/borg/manifest.py
@@ -28,7 +28,8 @@ class MandatoryFeatureUnsupported(Error):
 
 ArchiveInfo = namedtuple("ArchiveInfo", "name id ts")
 
-AI_HUMAN_SORT_KEYS = ["timestamp"] + list(ArchiveInfo._fields)
+# timestamp is a replacement for ts, archive is an alias for name (see SortBySpec)
+AI_HUMAN_SORT_KEYS = ["timestamp", "archive"] + list(ArchiveInfo._fields)
 AI_HUMAN_SORT_KEYS.remove("ts")
 
 


Test patch:
Repository: borgbackup/borg

Issue:
setup_requires is deprecated
## Have you checked borgbackup docs, FAQ, and open Github issues?

Yes

## Is this a BUG / ISSUE report or a QUESTION?

ISSUE

## System information. For client/server mode post info for both machines.

#### Your borg version (borg -V).

tip of  the 1.1-maint branch (c9833911)

#### Operating system (distribution) and version.

Fedora release 33 (Thirty Three)
<!--
#### Hardware / network configuration, and filesystems used.

#### How much data is handled by borg?
-->
#### Full borg commandline that lead to the problem (leave away excludes and passwords)

```
fakeroot -u tox --develop -e py3 borg.testsuite -- -k basic_functionality
```

## Describe the problem you're observing.
A warning is printed:
```
/home/user/borg/.tox/py3/lib/python3.9/site-packages/setuptools/__init__.py:148: SetuptoolsDeprecationWarning: setup_requires is deprecated. Supply build dependencies using PEP 517 pyproject.toml build-requires.
```

#### Can you reproduce the problem? If so, describe how. If not, describe troubleshooting steps you took before opening the issue.

1. Checkout the git source
2. Install dependencies
2. Run the above command
<!--
#### Include any warning/errors/backtraces from the system logs



If this complaint relates to borg performance, please include CRUD benchmark
results and any steps you took to troubleshoot.
How to run benchmark: http://borgbackup.readthedocs.io/en/stable/usage/benchmark.html

*IMPORTANT* - Please mark logs and text output from terminal commands 
or else Github will not display them correctly. 
An example is provided below.

Example:
```
this is an example how log text should be marked (wrap it with ```)
```
-->



Discussion:
I understand the sentiment, as the maintainer of the pulled in setup requires dependency however i have to make clear that the line is left there for support with the build /install processes of legacy/stable distros

I hope we can eventually remove /change things so this works with modern setuptools, however ancient setuptools are currently a necessary and painful concern 
I guess we can have some hope that this will be just a cosmetic problem with the warning while `1.1-maint` branch is still supported.

So, guess this ticket should be against `master` branch, where `setup_requires` is also used.
1.1.18 was last 1.1.x release, thus no change there.

1.2-maint still uses `setup_requires` in `setup.py`, but already has a `pyproject.toml` with `build-requires`, so we can just remove the entry in setup.py when it goes from deprecated to unsupported **or** when we're quite sure everybody has a recent enough python tools.

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -306,7 +306,6 @@ def members_appended(*ds):
     },
     cmdclass=cmdclass,
     ext_modules=ext_modules,
-    setup_requires=['setuptools_scm>=1.7'],
     install_requires=install_requires,
     extras_require=extras_require,
     python_requires='>=3.9',


Test patch:
Repository: borgbackup/borg

Issue:
officially switch to cython3 for borg >= 1.4
In borg 1.2-maint, I still made the bundled `*.c` files by cythonizing with cython 0.29.latest - because that is what we used for a long time in the past.

Considering we'll give borg 1.4 some testing before it will get a production release, that is a good time to switch to the now rather well-established Cython 3.0.x and drop support for Cython 0.29.x.



Discussion:

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -243,9 +243,9 @@ def members_appended(*ds):
 
     if cythonize and cythonizing:
         cython_opts = dict(
-            # default language_level will be '3str' starting from Cython 3.0.0,
-            # but old cython versions (< 0.29) do not know that, thus we use 3 for now.
-            compiler_directives={'language_level': 3},
+            # 3str is the default in Cython3 and we do not support older Cython releases.
+            # we only set this to avoid the related FutureWarning from Cython3.
+            compiler_directives={'language_level': '3str'}
         )
         if not is_win32:
             # compile .pyx extensions to .c in parallel, does not work on windows


Test patch:
Repository: borgbackup/borg

Issue:
what is EBUSY?
In #126, there was a mention of EBUSY.

Not familiar with this, when exactly can a file be "busy"?

Is this a platform specific thing?

How to deal with this for backup source files?


Discussion:
EBUSY  Device or resource busy (POSIX.1-2001)
https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_03

> [EBUSY]
> Resource busy. An attempt was made to make use of a system resource that is not currently available, as it is being used by another process in a manner that would have conflicted with the request being made by this process.


https://www.gnu.org/software/libc/manual/html_node/Error-Codes.html
> Macro: int EBUSY
> “Device or resource busy.” A system resource that can’t be shared is already in use. For example, if you try to delete a file that is the root of a currently mounted filesystem,  you get this error.
https://linux.die.net/HOWTO/SCSI-Generic-HOWTO/open.html
https://linux.die.net/HOWTO/SCSI-Generic-HOWTO/errors.html

Resolving patch:
diff --git a/src/borg/archive.py b/src/borg/archive.py
--- a/src/borg/archive.py
+++ b/src/borg/archive.py
@@ -195,6 +195,7 @@ def __exit__(self, exc_type, exc_val, exc_tb):
             E_MAP = {
                 errno.EPERM: BackupPermissionError,
                 errno.EACCES: BackupPermissionError,
+                errno.EBUSY: BackupPermissionError,
                 errno.ENOENT: BackupFileNotFoundError,
                 errno.EIO: BackupIOError,
             }


Test patch: