Recent changes to this wiki:

Added a comment: Any way to delete a remote?
diff --git a/doc/special_remotes/comment_46_f3f5348ceeffb458bcd7bfaa5c420751._comment b/doc/special_remotes/comment_46_f3f5348ceeffb458bcd7bfaa5c420751._comment
new file mode 100644
index 000000000..ddb890958
--- /dev/null
+++ b/doc/special_remotes/comment_46_f3f5348ceeffb458bcd7bfaa5c420751._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="tomdhunt"
+ avatar="http://cdn.libravatar.org/avatar/02694633d0fb05bb89f025cf779218a3"
+ subject="Any way to delete a remote?"
+ date="2021-03-07T01:53:21Z"
+ content="""
+I can't find any way to delete a special remote. I created one that was explicitly temporary (to transfer between some other systems), and now I can't get rid of it. I've already run \"git remote rm\" on it, but it seems git-annex didn't pick this up.
+"""]]

Added a comment
diff --git a/doc/forum/git_annex_sync_remove_all_recently_added_files/comment_2_27a56e101f7c3fcba90b4c69fa39f4c4._comment b/doc/forum/git_annex_sync_remove_all_recently_added_files/comment_2_27a56e101f7c3fcba90b4c69fa39f4c4._comment
new file mode 100644
index 000000000..8a0aa7b05
--- /dev/null
+++ b/doc/forum/git_annex_sync_remove_all_recently_added_files/comment_2_27a56e101f7c3fcba90b4c69fa39f4c4._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="qiang.fang@ddaed0de00c2925f8036e6c61ce6e12654263ada"
+ nickname="qiang.fang"
+ avatar="http://cdn.libravatar.org/avatar/5a55c6bcb3eaacde1355f9aca0d9384a"
+ subject="comment 2"
+ date="2021-03-06T00:03:51Z"
+ content="""
+Are you working on different computers?
+Is the system time in sync?
+"""]]

close todo
diff --git a/CHANGELOG b/CHANGELOG
index 100d12a36..33b0dc89f 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -8,6 +8,13 @@ git-annex (8.20210224) UNRELEASED; urgency=medium
   * Fixed handling of --mimetype or --mimeencoding combined with
     options like --all or --unused.
   * Fix handling of --branch combined with --unlocked or --locked.
+  * When non-annexed files in a tree are exported to a special remote,
+    importing from the special remote keeps the files non-annexed,
+    as long as their content has not changed, rather than converting
+    them to annexed files. 
+    (Such a conversion will still happen when importing from a remote
+    an old git-annex exported such a tree to before; export the tree
+    with the new git-annex before importing to avoid that.)
 
  -- Joey Hess <id@joeyh.name>  Wed, 24 Feb 2021 13:18:38 -0400
 
diff --git a/doc/forum/__96__git_annex_import__96___from_directory_loses_contents__63__/comment_2_c36d32db2b1dcd3cd36c68f2bb726f6f._comment b/doc/forum/__96__git_annex_import__96___from_directory_loses_contents__63__/comment_2_c36d32db2b1dcd3cd36c68f2bb726f6f._comment
new file mode 100644
index 000000000..db24d689d
--- /dev/null
+++ b/doc/forum/__96__git_annex_import__96___from_directory_loses_contents__63__/comment_2_c36d32db2b1dcd3cd36c68f2bb726f6f._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 2"""
+ date="2021-03-05T18:35:54Z"
+ content="""
+This bug has been fixed.
+
+And next time you have a problem so blatent with a test case and
+everything, it's certianly a bug, so don't be afraid to file a bug report
+rather than using the forum. It's harder to close forum posts than
+bug reports!
+"""]]
diff --git a/doc/todo/import_tree_annexes_files_that_were_exported_non-annexed.mdwn b/doc/todo/import_tree_annexes_files_that_were_exported_non-annexed.mdwn
index 370c80381..c70b37e9e 100644
--- a/doc/todo/import_tree_annexes_files_that_were_exported_non-annexed.mdwn
+++ b/doc/todo/import_tree_annexes_files_that_were_exported_non-annexed.mdwn
@@ -11,3 +11,5 @@ The importer could check for each file, if there's a corresponding file in
 the branch it's generating the import for, if that file is annexed.
 This corresponds to how git-annex add (and the smudge filter) handles these
 files. But this might be slow when importing a large tree of files.
+
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/todo/import_tree_annexes_files_that_were_exported_non-annexed/comment_2_7198cc839a881e53636899ecbc3ba785._comment b/doc/todo/import_tree_annexes_files_that_were_exported_non-annexed/comment_2_7198cc839a881e53636899ecbc3ba785._comment
new file mode 100644
index 000000000..50db1bd5d
--- /dev/null
+++ b/doc/todo/import_tree_annexes_files_that_were_exported_non-annexed/comment_2_7198cc839a881e53636899ecbc3ba785._comment
@@ -0,0 +1,30 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 2"""
+ date="2021-03-05T16:42:03Z"
+ content="""
+> The importer could check for each file, if there's a corresponding file in the branch it's generating the import for, if that file is annexed. 
+
+Should it check the branch it's generating the import for though?
+If the non-annexed file is "foo" and master is exported, then in master
+that file is renamed to "bar", the import should not look at the new master
+to see if the "foo" from the remote should be annexed. The correct tree
+to consult would be the tree that was exported to the remote last.
+
+It seems reasonable to look at the file in that exported tree to see it was
+non-annexed before, and if the ContentIdentifier is the same as what
+was exported before, keep it non-annexed on import. If the ContentIdentifier
+has changed, apply annex.largefiles to decide whether or not to annex it.
+
+The export database stores information about that tree already,
+but it does not keep track of whether a file was exported annexed or not.
+So changing the database to include an indication of that, and using it
+when importing, seems like a way to solve this problem, and without slowing
+things down much.
+
+*Alternatively* the GitKey that git-annex uses for these files when
+exporting is represented as a SHA1 key with no size field. That's unusual;
+nothing else creates such a key usually. (Although some advanced users may
+for some reason.) Just treating such keys as non-annexed files when
+importing would be at least a bandaid if not a real fix.
+"""]]
diff --git a/doc/todo/import_tree_annexes_files_that_were_exported_non-annexed/comment_3_5e24f3c713cbfd8e972243629282b7d9._comment b/doc/todo/import_tree_annexes_files_that_were_exported_non-annexed/comment_3_5e24f3c713cbfd8e972243629282b7d9._comment
new file mode 100644
index 000000000..aec821afa
--- /dev/null
+++ b/doc/todo/import_tree_annexes_files_that_were_exported_non-annexed/comment_3_5e24f3c713cbfd8e972243629282b7d9._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 3"""
+ date="2021-03-05T17:31:32Z"
+ content="""
+Wait... The import code has a separate "GIT" key type that it uses
+internally once it's decided a file should be non-annexed. Currently
+that never hits disk. Using that rather than a SHA1 key for the export
+database could be a solution. 
+
+(Using that rather than "SHA1" for the keys would also avoid
+the problem that the current GitKey hardcods an assumption 
+that git uses sha1..)
+"""]]
diff --git a/doc/todo/import_tree_annexes_files_that_were_exported_non-annexed/comment_4_c271a7a5530cbd2057140d81c364d45a._comment b/doc/todo/import_tree_annexes_files_that_were_exported_non-annexed/comment_4_c271a7a5530cbd2057140d81c364d45a._comment
new file mode 100644
index 000000000..4bae0d72f
--- /dev/null
+++ b/doc/todo/import_tree_annexes_files_that_were_exported_non-annexed/comment_4_c271a7a5530cbd2057140d81c364d45a._comment
@@ -0,0 +1,32 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 4"""
+ date="2021-03-05T17:44:54Z"
+ content="""
+In fact, a very simple patch that just makes a GitKey generate a
+"GIT" key seems to have solved this problem! Files that were non-annexed
+on export remain so on import, until they're changed, and then
+annex.largefiles controls what happens.
+
+Once non-annexed files have been exported using the new version, they'll
+stay non-annexed on import. Even when an old version of git-annex is doing
+the importing!
+
+When an old annex had exported, and a new one imports, what happens is
+the file gets imported as an annexed file. Exporting first with the new
+version avoids that unwanted conversion. 
+
+Interestingly though, the annexed file when that conversion happens does
+not use the SHA1 key from git, so its content can be retrieved. I'm not
+quite sure how that problem was avoided in this case but something avoided
+the worst behavior.
+
+It would be possible to special case the handling of SHA1 keys without a
+size to make importing from an old export not do the conversion. But that
+risks breakage for some user who is generating their own SHA1 keys and not
+including a size in them. Or for some external special remote that supports
+IMPORTKEY and generates SHA1 keys without a size. It seems better to avoid
+that potential breakage of unrelated things, and keep the upgrade process
+somewhat complicated when non-annexed files were exported before, than it
+does to streamline the upgrade.
+"""]]

use GIT keys for export of non-annexed files
This solves the problem that import of such files gets confused and
converts them back to annexed files.
The import code already used GIT keys internally when it determined a
file should not be annexed. So now when it sees a GIT key that export
used, it already does the right thing.
This also means that even older version of git-annex can import and will
do the right thing, once a fixed version has exported. Still, there may
be other complications around upgrades; still need to think it all
through.
Moved gitShaKey and keyGitSha from Key to Annex.Export since they're
only used for export/import.
Documented GIT keys in backends, since they do appear in the git-annex
branch now.
This commit was sponsored by Graham Spencer on Patreon.
diff --git a/Annex/Export.hs b/Annex/Export.hs
index b7e83dd74..bc66ef1b5 100644
--- a/Annex/Export.hs
+++ b/Annex/Export.hs
@@ -1,10 +1,12 @@
 {- git-annex exports
  -
- - Copyright 2017 Joey Hess <id@joeyh.name>
+ - Copyright 2017-2021 Joey Hess <id@joeyh.name>
  -
  - Licensed under the GNU AGPL version 3 or higher.
  -}
 
+{-# LANGUAGE OverloadedStrings #-}
+
 module Annex.Export where
 
 import Annex
@@ -15,31 +17,36 @@ import qualified Git
 import qualified Types.Remote as Remote
 import Messages
 
-import Control.Applicative
-import Data.Maybe
-import Prelude
-
--- An export includes both annexed files and files stored in git.
--- For the latter, a SHA1 key is synthesized.
-data ExportKey = AnnexKey Key | GitKey Key
-	deriving (Show, Eq, Ord)
-
-asKey :: ExportKey -> Key
-asKey (AnnexKey k) = k
-asKey (GitKey k) = k
-
-exportKey :: Git.Sha -> Annex ExportKey
+-- From a sha pointing to the content of a file to the key
+-- to use to export it. When the file is annexed, it's the annexed key.
+-- When the file is stored in git, it's a special type of key to indicate
+-- that.
+exportKey :: Git.Sha -> Annex Key
 exportKey sha = mk <$> catKey sha
   where
-	mk (Just k) = AnnexKey k
-	mk Nothing = GitKey $ mkKey $ \k -> k
-		{ keyName = Git.fromRef' sha
-		, keyVariety = SHA1Key (HasExt False)
-		, keySize = Nothing
-		, keyMtime = Nothing
-		, keyChunkSize = Nothing
-		, keyChunkNum = Nothing
-		}
+	mk (Just k) = k
+	mk Nothing = gitShaKey sha
+
+-- Encodes a git sha as a key. This is used to represent a non-annexed
+-- file that is stored on a special remote, which necessarily needs a
+-- key.
+--
+-- This is not the same as a SHA1 key, because the mapping needs to be
+-- bijective, also because git may not always use SHA1, and because git
+-- takes a SHA1 of the file size + content, while git-annex SHA1 keys
+-- only checksum the content.
+gitShaKey :: Git.Sha -> Key
+gitShaKey (Git.Ref s) = mkKey $ \kd -> kd
+	{ keyName = s
+	, keyVariety = OtherKey "GIT"
+	}
+
+-- Reverse of gitShaKey
+keyGitSha :: Key -> Maybe Git.Sha
+keyGitSha k
+	| fromKey keyVariety k == OtherKey "GIT" =
+		Just (Git.Ref (fromKey keyName k))
+	| otherwise = Nothing
 
 warnExportImportConflict :: Remote -> Annex ()
 warnExportImportConflict r = do
diff --git a/Annex/Import.hs b/Annex/Import.hs
index 9b421b59d..ba535b3eb 100644
--- a/Annex/Import.hs
+++ b/Annex/Import.hs
@@ -179,10 +179,11 @@ recordImportTree remote importtreeconfig importable = do
 	updatelocationlog oldexport finaltree = do
 		let stillpresent db k = liftIO $ not . null
 			<$> Export.getExportedLocation db k
-		let updater db oldkey _newkey _ = case oldkey of
-			Just (AnnexKey k) -> unlessM (stillpresent db k) $
-				logChange k (Remote.uuid remote) InfoMissing
-			Just (GitKey _) -> noop
+		let updater db moldkey _newkey _ = case moldkey of
+			Just oldkey -> case keyGitSha oldkey of
+				Nothing -> unlessM (stillpresent db oldkey) $
+					logChange oldkey (Remote.uuid remote) InfoMissing
+				Just _ -> noop
 			Nothing -> noop
 		db <- Export.openDb (Remote.uuid remote)
 		forM_ (exportedTreeishes oldexport) $ \oldtree ->
diff --git a/Command/Export.hs b/Command/Export.hs
index efbe893cc..fa0920f69 100644
--- a/Command/Export.hs
+++ b/Command/Export.hs
@@ -72,9 +72,9 @@ optParser _ = ExportOptions
 
 -- To handle renames which swap files, the exported file is first renamed
 -- to a stable temporary name based on the key.
-exportTempName :: ExportKey -> ExportLocation
+exportTempName :: Key -> ExportLocation
 exportTempName ek = mkExportLocation $ toRawFilePath $
-	".git-annex-tmp-content-" ++ serializeKey (asKey (ek))
+	".git-annex-tmp-content-" ++ serializeKey ek
 
 seek :: ExportOptions -> CommandSeek
 seek o = startConcurrency commandStages $ do
@@ -203,8 +203,8 @@ changeExport r db (PreferredFiltered new) = do
 		sequence_ $ map a diff
 		void $ liftIO cleanup
 
--- Map of old and new filenames for each changed ExportKey in a diff.
-type DiffMap = M.Map ExportKey (Maybe TopFilePath, Maybe TopFilePath)
+-- Map of old and new filenames for each changed Key in a diff.
+type DiffMap = M.Map Key (Maybe TopFilePath, Maybe TopFilePath)
 
 mkDiffMap :: Git.Ref -> Git.Ref -> ExportHandle -> Annex DiffMap
 mkDiffMap old new db = do
@@ -259,7 +259,7 @@ startExport r db cvar allfilledvar ti = do
 	ek <- exportKey (Git.LsTree.sha ti)
 	stopUnless (notrecordedpresent ek) $
 		starting ("export " ++ name r) ai si $
-			ifM (either (const False) id <$> tryNonAsync (checkPresentExport (exportActions r) (asKey ek) loc))
+			ifM (either (const False) id <$> tryNonAsync (checkPresentExport (exportActions r) ek loc))
 				( next $ cleanupExport r db ek loc False
 				, do
 					liftIO $ modifyMVar_ cvar (pure . const (FileUploaded True))
@@ -272,39 +272,39 @@ startExport r db cvar allfilledvar ti = do
 	ai = ActionItemOther (Just (fromRawFilePath f))
 	si = SeekInput []
 	notrecordedpresent ek = (||)
-		<$> liftIO (notElem loc <$> getExportedLocation db (asKey ek))
+		<$> liftIO (notElem loc <$> getExportedLocation db ek)
 		-- If content was removed from the remote, the export db
 		-- will still list it, so also check location tracking.
-		<*> (notElem (uuid r) <$> loggedLocations (asKey ek))
+		<*> (notElem (uuid r) <$> loggedLocations ek)
 
-performExport :: Remote -> ExportHandle -> ExportKey -> AssociatedFile -> Sha -> ExportLocation -> MVar AllFilled -> CommandPerform
+performExport :: Remote -> ExportHandle -> Key -> AssociatedFile -> Sha -> ExportLocation -> MVar AllFilled -> CommandPerform
 performExport r db ek af contentsha loc allfilledvar = do
 	let storer = storeExport (exportActions r)
-	sent <- tryNonAsync $ case ek of
-		AnnexKey k -> ifM (inAnnex k)
+	sent <- tryNonAsync $ case keyGitSha ek of
+		Nothing -> ifM (inAnnex ek)
 			( notifyTransfer Upload af $
 				-- alwaysUpload because the same key
 				-- could be used for more than one export
 				-- location, and concurrently uploading
 				-- of the content should still be allowed.
-				alwaysUpload (uuid r) k af Nothing stdRetry $ \pm -> do
+				alwaysUpload (uuid r) ek af Nothing stdRetry $ \pm -> do
 					let rollback = void $
 						performUnexport r db [ek] loc
-					sendAnnex k rollback $ \f ->
+					sendAnnex ek rollback $ \f ->
 						Remote.action $
-							storer f k loc pm
+							storer f ek loc pm
 			, do
 				showNote "not available"
 				return False
 			)
 		-- Sending a non-annexed file.
-		GitKey sha1k ->
+		Just _ ->
 			withTmpFile "export" $ \tmp h -> do
 				b <- catObject contentsha
 				liftIO $ L.hPut h b
 				liftIO $ hClose h
 				Remote.action $
-					storer tmp sha1k loc nullMeterUpdate
+					storer tmp ek loc nullMeterUpdate
 	let failedsend = liftIO $ modifyMVar_ allfilledvar (pure . const (AllFilled False))
 	case sent of
 		Right True -> next $ cleanupExport r db ek loc True
@@ -315,11 +315,11 @@ performExport r db ek af contentsha loc allfilledvar = do
 			failedsend
 			throwM err
 
-cleanupExport :: Remote -> ExportHandle -> ExportKey -> ExportLocation -> Bool -> CommandCleanup
+cleanupExport :: Remote -> ExportHandle -> Key -> ExportLocation -> Bool -> CommandCleanup
 cleanupExport r db ek loc sent = do
-	liftIO $ addExportedLocation db (asKey ek) loc
+	liftIO $ addExportedLocation db ek loc
 	when sent $
-		logChange (asKey ek) (uuid r) InfoPresent
+		logChange ek (uuid r) InfoPresent
 	return True
 
 startUnexport :: Remote -> ExportHandle -> TopFilePath -> [Git.Sha] -> CommandStart
@@ -335,7 +335,7 @@ startUnexport r db f shas = do

(Diff truncated)
forgot to add this comment earlier
diff --git a/doc/bugs/find_--branch__58___no_results_with_--__123__un__44____125__locked/comment_3_b68abf3a46bf0137c02e439c58ce0014._comment b/doc/bugs/find_--branch__58___no_results_with_--__123__un__44____125__locked/comment_3_b68abf3a46bf0137c02e439c58ce0014._comment
new file mode 100644
index 000000000..0d19fde16
--- /dev/null
+++ b/doc/bugs/find_--branch__58___no_results_with_--__123__un__44____125__locked/comment_3_b68abf3a46bf0137c02e439c58ce0014._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 3"""
+ date="2021-03-02T17:40:57Z"
+ content="""
+Ah yes, it's using git ls-tree so it can just check if the mode is that of
+a symlink or a file to tell if it's unlocked, so no need to mess with
+catKey.
+
+Ok, got --branch combined --unlocked/--locked working! Also in whereis and
+whatever other commands support --branch.
+"""]]

comment
diff --git a/doc/forum/__96__git_annex_import__96___from_directory_loses_contents__63__/comment_1_776b5b8099125aad3bc8839d9cc1abeb._comment b/doc/forum/__96__git_annex_import__96___from_directory_loses_contents__63__/comment_1_776b5b8099125aad3bc8839d9cc1abeb._comment
new file mode 100644
index 000000000..64ec49aa6
--- /dev/null
+++ b/doc/forum/__96__git_annex_import__96___from_directory_loses_contents__63__/comment_1_776b5b8099125aad3bc8839d9cc1abeb._comment
@@ -0,0 +1,29 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 1"""
+ date="2021-03-05T16:29:35Z"
+ content="""
+The conversion of the git file to an annexed file is a known problem, 
+<https://git-annex.branchable.com/todo/import_tree_annexes_files_that_were_exported_non-annexed/>
+
+The failure to get the content of the file when that happens is a bug
+though. (I think it may be a reversion as I seem to remember that working,
+but I could be mistaken.)
+
+It seems to be caused by an underlying inability to get the file:
+
+	get file.txt (from test...) (checksum...) 
+	  verification of content failed
+
+Which in turn is due to a confusion between two different SHA1s.
+When exporting a file stored in git, git-annex use the SHA1 git uses for it,
+but that is not actually the SHA1 of the file, but of the file size and file
+or something like that. Then when the file gets converted to an annexed
+file, it uses a git-annex get with that same SHA1. But git-annex expects
+the content of a SHA1 keyed file to match that SHA1, which is not the case here.
+
+So verification fails, and that's also why importing doesn't get the content.
+
+This is certainly a bug. I guess the best way to fix it would be to fix
+the above todo.
+"""]]
diff --git a/doc/todo/import_tree_annexes_files_that_were_exported_non-annexed/comment_1_bc28c34fcbd86b39c2ee7d9051315f92._comment b/doc/todo/import_tree_annexes_files_that_were_exported_non-annexed/comment_1_bc28c34fcbd86b39c2ee7d9051315f92._comment
new file mode 100644
index 000000000..7b7293e82
--- /dev/null
+++ b/doc/todo/import_tree_annexes_files_that_were_exported_non-annexed/comment_1_bc28c34fcbd86b39c2ee7d9051315f92._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 1"""
+ date="2021-03-05T16:38:25Z"
+ content="""
+This leads to worse behavior than just converting to annexed from
+non-annexed. The converted file's contents don't verify due to some
+confusion between git and git-annex's use of SHA1. See 
+<https://git-annex.branchable.com/forum/__96__git_annex_import__96___from_directory_loses_contents__63__/>
+"""]]

comment
diff --git a/doc/forum/error__58___bogus_format_in_GIT__95__CONFIG__95__PARAMETERS/comment_1_aa740c16099f24fd8a067ef23435d0d4._comment b/doc/forum/error__58___bogus_format_in_GIT__95__CONFIG__95__PARAMETERS/comment_1_aa740c16099f24fd8a067ef23435d0d4._comment
new file mode 100644
index 000000000..d85905d5a
--- /dev/null
+++ b/doc/forum/error__58___bogus_format_in_GIT__95__CONFIG__95__PARAMETERS/comment_1_aa740c16099f24fd8a067ef23435d0d4._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 1"""
+ date="2021-03-05T16:16:16Z"
+ content="""
+The git-annex.linux directory from the bundle does include a git, so if you
+put that directory in PATH first, it will avoid the problem.
+
+This should be a fairly transient problem, since the git-annex bundle is
+built with the version of git from debian unstable. Once the new git
+version gets released, it should fairly quickly get in there and the
+incompatability will stop being a problem.
+"""]]

diff --git a/doc/forum/error__58___bogus_format_in_GIT__95__CONFIG__95__PARAMETERS.mdwn b/doc/forum/error__58___bogus_format_in_GIT__95__CONFIG__95__PARAMETERS.mdwn
new file mode 100644
index 000000000..8d6f88f7d
--- /dev/null
+++ b/doc/forum/error__58___bogus_format_in_GIT__95__CONFIG__95__PARAMETERS.mdwn
@@ -0,0 +1,52 @@
+Using [the precompiled git-annex distribution](https://downloads.kitenet.net/git-annex/linux/current/git-annex-standalone-amd64.tar.gz), I have encountered a problem which looks like this:
+
+    git -c foo.bar=baz annex sync
+    error: bogus format in GIT_CONFIG_PARAMETERS
+    fatal: unable to parse command-line config
+    git-annex: user error (git ["config","--null","--list"] exited 128)
+
+I believe I understand what is causing this, and it's not a bug with git-annex.  But I thought it would be worth reporting here in case anyone else encounters similar issues in the future.
+
+On my system I have three different git installations:
+
+- The one in `/usr/bin/git` etc. provided by the distribution package (version 2.28.0)
+- One I've compiled myself in my home directory from a recent upstream `master`, accessible via `~/bin/git` (version 2.30.1.490.ge54fde04c8.dirty)
+- The one embedded in the git-annex bundle obtained from the above link, which I've put under `~/software/scm/git-annex.static/` (`~/software/scm/git-annex.static/shimmed/git/git --version` reports version 2.30.1)
+
+Normally `~/bin` is near the front of my `$PATH`, so my hand-compiled git is used whenever I run `git some-command`.  If I place the following executable script at `~/bin/git-show-config-params`:
+
+    #!/bin/sh
+    echo "$GIT_CONFIG_PARAMETERS"
+
+then it can be seen there's a difference between the versions in how `GIT_CONFIG_PARAMETERS` is constructed:
+
+    % ~/bin/git -c foo.bar=baz show-config-params
+    'foo.bar'='baz'
+    % /usr/bin/git -c foo.bar=baz show-config-params
+    'foo.bar=baz'
+    % ~/software/scm/git-annex.static/shimmed/git/git -c foo.bar=baz show-config-params
+    'foo.bar=baz'
+
+This appears to be due to [commit 294e949fa from 2021-01-25](https://git.kernel.org/pub/scm/git/git.git/commit/?id=294e949fa2dfd43097b2b5614470a3e43604663d) which first appeared in the tag `v2.31.0-rc0`.
+
+This commit is also required in order to successfully parse the new format:
+
+    % GIT_CONFIG_PARAMETERS="'foo.bar'='baz'" ~/software/scm/git-annex.static/shimmed/git/git branch
+    error: bogus format in GIT_CONFIG_PARAMETERS
+    fatal: unable to parse command-line config
+    % GIT_CONFIG_PARAMETERS="'foo.bar'='baz'" /usr/bin/git branch
+    error: bogus format in GIT_CONFIG_PARAMETERS
+    fatal: unable to parse command-line config
+    % GIT_CONFIG_PARAMETERS="'foo.bar'='baz'" ~/bin/git branch
+      git-annex
+    * master
+      synced/git-annex
+      synced/master
+
+So now we can fully understand the cause: when I run
+
+    git -c foo.bar=baz annex sync
+
+it first invokes the newer hand-compiled git with this patch, resulting in `GIT_CONFIG_PARAMETERS` being set to `'foo.bar'='baz'`.  That environment variable is then passed through various wrappers to `~/software/scm/git-annex.static/shimmed/git/git`, which does not know how to parse the new format, hence the `bogus format` error.
+
+The solution is to avoid using the newer development version of git as the "outer" git, since it's not backwards compatible in this respect.  If the two versions were switched around, i.e. the older one setting `GIT_CONFIG_PARAMETERS` and the newer parsing it, that would have worked fine, but of course that's not how the `git annex` wrapper system works.

diff --git a/doc/forum/__96__git_annex_import__96___from_directory_loses_contents__63__.mdwn b/doc/forum/__96__git_annex_import__96___from_directory_loses_contents__63__.mdwn
index 7a2511ae0..f229f71fd 100644
--- a/doc/forum/__96__git_annex_import__96___from_directory_loses_contents__63__.mdwn
+++ b/doc/forum/__96__git_annex_import__96___from_directory_loses_contents__63__.mdwn
@@ -56,9 +56,9 @@ failed
 git-annex: get: 1 failed
 ```
 
-file.txt can not be retreived from the remote - this is not what I expected.
+file.txt can not be retrieved from the remote - this is not what I expected.
 
-- I expected to be able to retreive the file contents from the remote.
+- I expected to be able to retrieve the file contents from the remote.
 
 --
 

Fix `borg create` example (according to https://borgbackup.readthedocs.io/en/stable/usage/create.html#examples)
diff --git a/doc/special_remotes/borg.mdwn b/doc/special_remotes/borg.mdwn
index bc072c3db..47ec79199 100644
--- a/doc/special_remotes/borg.mdwn
+++ b/doc/special_remotes/borg.mdwn
@@ -10,7 +10,7 @@ about the annexed files that are stored in the borg repository.
 
 	# borg init --encryption=keyfile /path/to/borgrepo
 	# git annex initremote borg type=borg borgrepo=/path/to/borgrepo
-	# borg create /path/to/borgrepo `pwd`::{now}
+	# borg create /path/to/borgrepo::{now} `pwd`
 	# git annex sync borg
 
 ## configuration

Added a comment: thanks
diff --git a/doc/bugs/find_--branch__58___no_results_with_--__123__un__44____125__locked/comment_3_5299bafc9ae75788d2e7e9aa7f48d00e._comment b/doc/bugs/find_--branch__58___no_results_with_--__123__un__44____125__locked/comment_3_5299bafc9ae75788d2e7e9aa7f48d00e._comment
new file mode 100644
index 000000000..2b2e7b804
--- /dev/null
+++ b/doc/bugs/find_--branch__58___no_results_with_--__123__un__44____125__locked/comment_3_5299bafc9ae75788d2e7e9aa7f48d00e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="kyle"
+ avatar="http://cdn.libravatar.org/avatar/7d6e85cde1422ad60607c87fa87c63f3"
+ subject="thanks"
+ date="2021-03-02T20:51:52Z"
+ content="""
+Great, thank you!
+"""]]

fix --branch combined with --unlocked or --locked
Since it's using git ls-tree anyway, can just look at the file modes to see
if they're unlocked or are symlinks.
diff --git a/CHANGELOG b/CHANGELOG
index c1beb91d1..100d12a36 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -7,9 +7,7 @@ git-annex (8.20210224) UNRELEASED; urgency=medium
   * Prevent combinations of options such as --all with --include.
   * Fixed handling of --mimetype or --mimeencoding combined with
     options like --all or --unused.
-
-Also, made --mimetype combined with eg --all work, by looking at the
-object file when operating on keys.
+  * Fix handling of --branch combined with --unlocked or --locked.
 
  -- Joey Hess <id@joeyh.name>  Wed, 24 Feb 2021 13:18:38 -0400
 
diff --git a/CmdLine/Seek.hs b/CmdLine/Seek.hs
index 5cd036995..1681e522d 100644
--- a/CmdLine/Seek.hs
+++ b/CmdLine/Seek.hs
@@ -22,6 +22,7 @@ import qualified Git.LsFiles as LsFiles
 import qualified Git.LsTree as LsTree
 import qualified Git.Types as Git
 import qualified Git.Ref
+import Git.Types (toTreeItemType, TreeItemType(..))
 import Git.FilePath
 import qualified Limit
 import CmdLine.GitAnnex.Options
@@ -30,6 +31,7 @@ import Logs
 import Logs.Unused
 import Types.Transfer
 import Logs.Transfer
+import Types.Link
 import Remote.List
 import qualified Remote
 import Annex.CatFile
@@ -191,7 +193,7 @@ withKeyOptions ko auto seeker keyaction = withKeyOptions' ko auto mkkeyaction
   where
 	mkkeyaction = do
 		matcher <- Limit.getMatcher
-		return $ \v@(_si, k, ai) -> checkseeker k $
+		return $ \lt v@(_si, k, ai) -> checkseeker k $
 			let i = case ai of
 				ActionItemBranchFilePath (BranchFilePath _ topf) _ ->
 					ProvidedInfo
@@ -201,7 +203,7 @@ withKeyOptions ko auto seeker keyaction = withKeyOptions' ko auto mkkeyaction
 						, providedFileSize = Nothing
 						, providedMimeType = Nothing
 						, providedMimeEncoding = Nothing
-						, providedLinkType = Nothing
+						, providedLinkType = lt
 						}
 				_ -> ProvidedInfo
 					{ providedFilePath = Nothing
@@ -209,7 +211,7 @@ withKeyOptions ko auto seeker keyaction = withKeyOptions' ko auto mkkeyaction
 					, providedFileSize = Nothing
 					, providedMimeType = Nothing
 					, providedMimeEncoding = Nothing
-					, providedLinkType = Nothing
+					, providedLinkType = lt
 					}
 			in whenM (matcher (MatchingInfo i)) $
 				keyaction v
@@ -222,7 +224,7 @@ withKeyOptions ko auto seeker keyaction = withKeyOptions' ko auto mkkeyaction
 withKeyOptions' 
 	:: Maybe KeyOptions
 	-> Bool
-	-> Annex ((SeekInput, Key, ActionItem) -> Annex ())
+	-> Annex (Maybe LinkType -> (SeekInput, Key, ActionItem) -> Annex ())
 	-> (WorkTreeItems -> CommandSeek)
 	-> WorkTreeItems
 	-> CommandSeek
@@ -240,7 +242,7 @@ withKeyOptions' ko auto mkkeyaction fallbackaction worktreeitems = do
 		(True, Just WantFailedTransfers) -> nofilename $ noauto runfailedtransfers
 		(True, Just (WantSpecificKey k)) -> nofilename $ noauto $ runkeyaction (return [k])
 		(True, Just WantIncompleteKeys) -> nofilename $ noauto $ runkeyaction incompletekeys
-		(True, Just (WantBranchKeys bs)) -> nofilename $ noauto $ runbranchkeys bs
+		(True, Just (WantBranchKeys bs)) -> noauto $ runbranchkeys bs
 		(False, Just _) -> giveup "Can only specify one of file names, --all, --branch, --unused, --failed, --key, or --incomplete"
   where
 	noauto a
@@ -286,7 +288,7 @@ withKeyOptions' ko auto mkkeyaction fallbackaction worktreeitems = do
 			Nothing -> return ()
 			Just ((k, f), content) -> checktimelimit (discard reader) $ do
 				maybe noop (Annex.BranchState.setCache f) content
-				keyaction (SeekInput [], k, mkActionItem k)
+				keyaction Nothing (SeekInput [], k, mkActionItem k)
 				go reader
 		catObjectStreamLsTree l (getk . getTopFilePath . LsTree.file) g go
 		liftIO $ void cleanup
@@ -294,17 +296,22 @@ withKeyOptions' ko auto mkkeyaction fallbackaction worktreeitems = do
 	runkeyaction getks = do
 		keyaction <- mkkeyaction
 		ks <- getks
-		forM_ ks $ \k -> keyaction (SeekInput [], k, mkActionItem k)
+		forM_ ks $ \k -> keyaction Nothing (SeekInput [], k, mkActionItem k)
 	
 	runbranchkeys bs = do
 		keyaction <- mkkeyaction
 		forM_ bs $ \b -> do
 			(l, cleanup) <- inRepo $ LsTree.lsTree LsTree.LsTreeRecursive b
 			forM_ l $ \i -> catKey (LsTree.sha i) >>= \case
-				Nothing -> noop
 				Just k -> 
 					let bfp = mkActionItem (BranchFilePath b (LsTree.file i), k)
-					in keyaction (SeekInput [], k, bfp)
+					    lt = case toTreeItemType (LsTree.mode i) of
+						Just TreeSymlink -> Just LockedLink
+						Just TreeFile -> Just UnlockedLink
+						Just TreeExecutable -> Just UnlockedLink
+						_ -> Nothing
+					in keyaction lt (SeekInput [], k, bfp)
+				Nothing -> noop
 			unlessM (liftIO cleanup) $
 				error ("git ls-tree " ++ Git.fromRef b ++ " failed")
 	
@@ -313,7 +320,7 @@ withKeyOptions' ko auto mkkeyaction fallbackaction worktreeitems = do
 		rs <- remoteList
 		ts <- concat <$> mapM (getFailedTransfers . Remote.uuid) rs
 		forM_ ts $ \(t, i) ->
-			keyaction (SeekInput [], transferKey t, mkActionItem (t, i))
+			keyaction Nothing (SeekInput [], transferKey t, mkActionItem (t, i))
 
 seekFiltered :: ((SeekInput, RawFilePath) -> Annex Bool) -> ((SeekInput, RawFilePath) -> CommandSeek) -> Annex ([(SeekInput, RawFilePath)], IO Bool) -> Annex ()
 seekFiltered prefilter a listfs = do
diff --git a/Command/Sync.hs b/Command/Sync.hs
index ecd5b34db..6875e6000 100644
--- a/Command/Sync.hs
+++ b/Command/Sync.hs
@@ -711,7 +711,7 @@ seekSyncContent o rs currbranch = do
 				pure Nothing
 	waitForAllRunningCommandActions
 	withKeyOptions' (keyOptions o) False
-		(return (commandAction . gokey mvar bloom))
+		(return (const (commandAction . gokey mvar bloom)))
 		(const noop)
 		(WorkTreeItems [])
 	waitForAllRunningCommandActions
diff --git a/doc/bugs/find_--branch__58___no_results_with_--__123__un__44____125__locked.mdwn b/doc/bugs/find_--branch__58___no_results_with_--__123__un__44____125__locked.mdwn
index 9e56e2043..0d4e1cadb 100644
--- a/doc/bugs/find_--branch__58___no_results_with_--__123__un__44____125__locked.mdwn
+++ b/doc/bugs/find_--branch__58___no_results_with_--__123__un__44____125__locked.mdwn
@@ -80,3 +80,5 @@ Thanks in advance.
 
 [[!meta author=kyle]]
 [[!tag projects/datalad]]
+
+> [[fixed|done]] --[[Joey]]

diff --git a/doc/forum/__96__git_annex_import__96___from_directory_loses_contents__63__.mdwn b/doc/forum/__96__git_annex_import__96___from_directory_loses_contents__63__.mdwn
new file mode 100644
index 000000000..7a2511ae0
--- /dev/null
+++ b/doc/forum/__96__git_annex_import__96___from_directory_loses_contents__63__.mdwn
@@ -0,0 +1,76 @@
+I'm a bit confused by the behaviour of `git annex import` from directory special-remotes. It seems to move a file from git to the annex, and loses the file contents. Is this the expected behaviour?
+
+```
+$ mkdir export-directory
+
+$ mkdir repo
+
+$ cd repo/
+
+$ git init
+
+$ git annex init
+
+$ git annex initremote test type=directory directory=../export-directory encryption=none importtree=yes exporttree=yes
+
+$ git config remote.test.annex-tracking-branch master
+
+$ touch file.txt
+
+$ git annex add --force-small file.txt 
+
+$ git commit -m 'Add file to git'
+
+$ git annex sync --content (OR git annex export master --to test)
+
+$ ls -l
+total 0
+-rw-r--r-- 1 user user 0 Mar  2 18:56 file.txt
+
+$ git annex sync --content (OR git annex import master --from test && git annex merge test/master)
+
+$ ls -l
+total 4
+lrwxrwxrwx 1 user user 118 Mar  2 18:57 file.txt -> .git/annex/objects/25/F0/SHA1--e69de29bb2d1d6434b8b29ae775ad8c2e48c5391/SHA1--e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
+```
+
+file.txt is now a broken symlink to the annex - this is not what I expected.
+
+- I expected it to be a normal file.
+
+- If it is supposed to be moved to the annex, I would expect the file contents to be in the annex.
+
+```
+$ git annex whereis file.txt 
+whereis file.txt (0 copies) 
+  The following untrusted locations may also have copies:
+  	ce81dda1-e6cc-453a-9156-e067b8f70063 -- [test]
+failed
+git-annex: whereis: 1 failed
+
+$ git annex get file.txt --from test
+get file.txt (from test...) 
+(checksum...) 
+  verification of content failed
+failed
+git-annex: get: 1 failed
+```
+
+file.txt can not be retreived from the remote - this is not what I expected.
+
+- I expected to be able to retreive the file contents from the remote.
+
+--
+
+```
+$ git annex version
+git-annex version: 8.20200810
+build flags: Assistant Webapp Pairing S3 WebDAV Inotify DBus DesktopNotify TorrentParser MagicMime Feeds Testsuite
+dependency versions: aws-0.22 bloomfilter-2.0.1.0 cryptonite-0.27 DAV-1.3.4 feed-1.3.0.1 ghc-8.8.4 http-client-0.6.4.1 persistent-sqlite-2.10.6.2 torrent-10000.1.1 uuid-1.3.13 yesod-1.6.1.0
+key/value backends: SHA256E SHA256 SHA512E SHA512 SHA224E SHA224 SHA384E SHA384 SHA3_256E SHA3_256 SHA3_512E SHA3_512 SHA3_224E SHA3_224 SHA3_384E SHA3_384 SKEIN256E SKEIN256 SKEIN512E SKEIN512 BLAKE2B256E BLAKE2B256 BLAKE2B512E BLAKE2B512 BLAKE2B160E BLAKE2B160 BLAKE2B224E BLAKE2B224 BLAKE2B384E BLAKE2B384 BLAKE2BP512E BLAKE2BP512 BLAKE2S256E BLAKE2S256 BLAKE2S160E BLAKE2S160 BLAKE2S224E BLAKE2S224 BLAKE2SP256E BLAKE2SP256 BLAKE2SP224E BLAKE2SP224 SHA1E SHA1 MD5E MD5 WORM URL X*
+remote types: git gcrypt p2p S3 bup directory rsync web bittorrent webdav adb tahoe glacier ddar git-lfs hook external
+operating system: linux x86_64
+supported repository versions: 8
+upgrade supported from repository versions: 0 1 2 3 4 5 6 7
+local repository version: 8
+```

Prevent combinations of options such as --all with --include
Previously such nonsensical combinations always treated the matching option
as if it didn't match.
For now, made find --branch refuse matching options that need a
filename, because one is not provided to them in a way they'll use.
There's an open bug report to support it, but making it error out is
better than the old behavior of not finding what it was asked to.
Also, made --mimetype combined with eg --all work, by looking at the
object file when operating on keys.
diff --git a/CHANGELOG b/CHANGELOG
index c3debfd12..c1beb91d1 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -4,6 +4,12 @@ git-annex (8.20210224) UNRELEASED; urgency=medium
   * registerurl: Allow it to be used in a bare repository.
   * Windows: Correct the path to the html help file for 64 bit build.
   * uninit: Fix a small bug that left a lock file in .git/annex
+  * Prevent combinations of options such as --all with --include.
+  * Fixed handling of --mimetype or --mimeencoding combined with
+    options like --all or --unused.
+
+Also, made --mimetype combined with eg --all work, by looking at the
+object file when operating on keys.
 
  -- Joey Hess <id@joeyh.name>  Wed, 24 Feb 2021 13:18:38 -0400
 
diff --git a/CmdLine/Seek.hs b/CmdLine/Seek.hs
index 46ec0f67c..f6e9dee55 100644
--- a/CmdLine/Seek.hs
+++ b/CmdLine/Seek.hs
@@ -217,21 +217,30 @@ withKeyOptions' ko auto mkkeyaction fallbackaction worktreeitems = do
 		giveup "Cannot use --auto in a bare repository"
 	case (noworktreeitems, ko) of
 		(True, Nothing)
-			| bare -> noauto runallkeys
+			| bare -> nofilename $ noauto runallkeys
 			| otherwise -> fallbackaction worktreeitems
 		(False, Nothing) -> fallbackaction worktreeitems
-		(True, Just WantAllKeys) -> noauto runallkeys
-		(True, Just WantUnusedKeys) -> noauto $ runkeyaction unusedKeys'
-		(True, Just WantFailedTransfers) -> noauto runfailedtransfers
-		(True, Just (WantSpecificKey k)) -> noauto $ runkeyaction (return [k])
-		(True, Just WantIncompleteKeys) -> noauto $ runkeyaction incompletekeys
-		(True, Just (WantBranchKeys bs)) -> noauto $ runbranchkeys bs
+		(True, Just WantAllKeys) -> nofilename $ noauto runallkeys
+		(True, Just WantUnusedKeys) -> nofilename $ noauto $ runkeyaction unusedKeys'
+		(True, Just WantFailedTransfers) -> nofilename $ noauto runfailedtransfers
+		(True, Just (WantSpecificKey k)) -> nofilename $ noauto $ runkeyaction (return [k])
+		(True, Just WantIncompleteKeys) -> nofilename $ noauto $ runkeyaction incompletekeys
+		(True, Just (WantBranchKeys bs)) -> nofilename $ noauto $ runbranchkeys bs
 		(False, Just _) -> giveup "Can only specify one of file names, --all, --branch, --unused, --failed, --key, or --incomplete"
   where
 	noauto a
 		| auto = giveup "Cannot use --auto with --all or --branch or --unused or --key or --incomplete"
 		| otherwise = a
-	
+			
+	nofilename a = ifM (Limit.introspect matchNeedsFileName)
+		( do
+			bare <- fromRepo Git.repoIsLocalBare
+			if bare
+				then giveup "Cannot use options that match on file names in a bare repository."
+				else giveup "Cannot use --all or --unused or --key or --incomplete with options that match on file names."
+		, a
+		)
+
 	noworktreeitems = case worktreeitems of
 		WorkTreeItems [] -> True
 		WorkTreeItems _ -> False
diff --git a/Limit.hs b/Limit.hs
index 649c1c2c2..145b57291 100644
--- a/Limit.hs
+++ b/Limit.hs
@@ -159,14 +159,16 @@ matchMagic
 matchMagic _limitname querymagic selectprovidedinfo selectuserprovidedinfo (Just magic) glob = 
 	Right $ MatchFiles
 		{ matchAction = const go
-		, matchNeedsFileName = True
+		, matchNeedsFileName = False
 		, matchNeedsFileContent = True
 		, matchNeedsKey = False
 		, matchNeedsLocationLog = False
 		}
   where
  	cglob = compileGlob glob CaseSensative (GlobFilePath False) -- memoized
-	go (MatchingKey _ _) = pure False
+	go (MatchingKey k _) = withObjectLoc k $ \obj -> 
+		maybe False (matchGlob cglob)
+			<$> querymagic magic (fromRawFilePath obj)
 	go (MatchingFile fi) = case contentFile fi of
 		Just f -> catchBoolIO $
 			maybe False (matchGlob cglob)
diff --git a/doc/bugs/find_--branch__58___no_results_with_--__123__un__44____125__locked/comment_2_3f1980c96f795c30886b3decba69819d._comment b/doc/bugs/find_--branch__58___no_results_with_--__123__un__44____125__locked/comment_2_3f1980c96f795c30886b3decba69819d._comment
new file mode 100644
index 000000000..5a10b2d53
--- /dev/null
+++ b/doc/bugs/find_--branch__58___no_results_with_--__123__un__44____125__locked/comment_2_3f1980c96f795c30886b3decba69819d._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 2"""
+ date="2021-03-01T19:50:36Z"
+ content="""
+I've guarded against all the other bad combos mentioned. 
+
+find --branch --unlocked/--locked will be rejected now due to that change,
+but can be implemented later the way I discussed above.
+"""]]

move comment to correct bug
diff --git a/doc/bugs/find_--batch_reports_files_that_have_no_content/comment_1_d0dcd56a0af59bb53092c518a4e3eefd._comment b/doc/bugs/find_--branch__58___no_results_with_--__123__un__44____125__locked/comment_1_d0dcd56a0af59bb53092c518a4e3eefd._comment
similarity index 100%
rename from doc/bugs/find_--batch_reports_files_that_have_no_content/comment_1_d0dcd56a0af59bb53092c518a4e3eefd._comment
rename to doc/bugs/find_--branch__58___no_results_with_--__123__un__44____125__locked/comment_1_d0dcd56a0af59bb53092c518a4e3eefd._comment

unregisterurl: New command
Implemented by generalizing registerurl. Without the implicit batch mode
of registerurl since that is only a backwards compatability thing
(see commit 1d1054faa6989acb716d620266a0a0a8a2ec407e).
diff --git a/CHANGELOG b/CHANGELOG
index a11e54735..c3debfd12 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,8 +1,9 @@
 git-annex (8.20210224) UNRELEASED; urgency=medium
 
+  * unregisterurl: New command.
+  * registerurl: Allow it to be used in a bare repository.
   * Windows: Correct the path to the html help file for 64 bit build.
   * uninit: Fix a small bug that left a lock file in .git/annex
-  * registerurl: Allow it to be used in a bare repository.
 
  -- Joey Hess <id@joeyh.name>  Wed, 24 Feb 2021 13:18:38 -0400
 
diff --git a/CmdLine/GitAnnex.hs b/CmdLine/GitAnnex.hs
index ecf43678d..ac2b9b821 100644
--- a/CmdLine/GitAnnex.hs
+++ b/CmdLine/GitAnnex.hs
@@ -1,6 +1,6 @@
 {- git-annex main program
  -
- - Copyright 2010-2019 Joey Hess <id@joeyh.name>
+ - Copyright 2010-2021 Joey Hess <id@joeyh.name>
  -
  - Licensed under the GNU AGPL version 3 or higher.
  -}
@@ -33,6 +33,7 @@ import qualified Command.ExamineKey
 import qualified Command.MatchExpression
 import qualified Command.FromKey
 import qualified Command.RegisterUrl
+import qualified Command.UnregisterUrl
 import qualified Command.SetKey
 import qualified Command.DropKey
 import qualified Command.Transferrer
@@ -178,6 +179,7 @@ cmds testoptparser testrunner mkbenchmarkgenerator = map addGitAnnexGlobalOption
 	, Command.MatchExpression.cmd
 	, Command.FromKey.cmd
 	, Command.RegisterUrl.cmd
+	, Command.UnregisterUrl.cmd
 	, Command.SetKey.cmd
 	, Command.DropKey.cmd
 	, Command.Transferrer.cmd
diff --git a/Command/RegisterUrl.hs b/Command/RegisterUrl.hs
index 333c8d752..583b17014 100644
--- a/Command/RegisterUrl.hs
+++ b/Command/RegisterUrl.hs
@@ -32,43 +32,43 @@ optParser desc = RegisterUrlOptions
 
 seek :: RegisterUrlOptions -> CommandSeek
 seek o = case (batchOption o, keyUrlPairs o) of
-	(Batch fmt, _) -> commandAction $ startMass fmt
+	(Batch fmt, _) -> commandAction $ startMass setUrlPresent fmt
 	-- older way of enabling batch input, does not support BatchNull
-	(NoBatch, []) -> commandAction $ startMass BatchLine
-	(NoBatch, ps) -> withWords (commandAction . start) ps
+	(NoBatch, []) -> commandAction $ startMass setUrlPresent BatchLine
+	(NoBatch, ps) -> withWords (commandAction . start setUrlPresent) ps
 
-start :: [String] -> CommandStart
-start (keyname:url:[]) = 
+start :: (Key -> URLString -> Annex ()) -> [String] -> CommandStart
+start a (keyname:url:[]) = 
 	starting "registerurl" ai si $
-		perform (keyOpt keyname) url
+		perform a (keyOpt keyname) url
   where
 	ai = ActionItemOther (Just url)
 	si = SeekInput [keyname, url]
-start _ = giveup "specify a key and an url"
+start _ _ = giveup "specify a key and an url"
 
-startMass :: BatchFormat -> CommandStart
-startMass fmt = 
+startMass :: (Key -> URLString -> Annex ()) -> BatchFormat -> CommandStart
+startMass a fmt = 
 	starting "registerurl" (ActionItemOther (Just "stdin")) (SeekInput []) $
-		massAdd fmt
+		performMass a fmt
 
-massAdd :: BatchFormat -> CommandPerform
-massAdd fmt = go True =<< map (separate (== ' ')) <$> batchLines fmt
+performMass :: (Key -> URLString -> Annex ()) -> BatchFormat -> CommandPerform
+performMass a fmt = go True =<< map (separate (== ' ')) <$> batchLines fmt
   where
 	go status [] = next $ return status
 	go status ((keyname,u):rest) | not (null keyname) && not (null u) = do
 		let key = keyOpt keyname
-		ok <- perform' key u
+		ok <- perform' a key u
 		let !status' = status && ok
 		go status' rest
 	go _ _ = giveup "Expected pairs of key and url on stdin, but got something else."
 
-perform :: Key -> URLString -> CommandPerform
-perform key url = do
-	ok <- perform' key url
+perform :: (Key -> URLString -> Annex ()) -> Key -> URLString -> CommandPerform
+perform a key url = do
+	ok <- perform' a key url
 	next $ return ok
 
-perform' :: Key -> URLString -> Annex Bool
-perform' key url = do
+perform' :: (Key -> URLString -> Annex ()) -> Key -> URLString -> Annex Bool
+perform' a key url = do
 	r <- Remote.claimingUrl url
-	setUrlPresent key (setDownloader' url r)
+	a key (setDownloader' url r)
 	return True
diff --git a/Command/UnregisterUrl.hs b/Command/UnregisterUrl.hs
new file mode 100644
index 000000000..6a44248b2
--- /dev/null
+++ b/Command/UnregisterUrl.hs
@@ -0,0 +1,25 @@
+{- git-annex command
+ -
+ - Copyright 2015-2021 Joey Hess <id@joeyh.name>
+ -
+ - Licensed under the GNU AGPL version 3 or higher.
+ -}
+
+{-# LANGUAGE BangPatterns #-}
+
+module Command.UnregisterUrl where
+
+import Command
+import Logs.Web
+import Command.RegisterUrl (start, startMass, optParser, RegisterUrlOptions(..))
+
+cmd :: Command
+cmd = command "unregisterurl"
+	SectionPlumbing "unregisters an url for a key"
+	(paramPair paramKey paramUrl)
+	(seek <$$> optParser)
+
+seek :: RegisterUrlOptions -> CommandSeek
+seek o = case (batchOption o, keyUrlPairs o) of
+	(Batch fmt, _) -> commandAction $ startMass setUrlMissing fmt
+	(NoBatch, ps) -> withWords (commandAction . start setUrlMissing) ps
diff --git a/doc/git-annex-registerurl.mdwn b/doc/git-annex-registerurl.mdwn
index 0a2cf4e42..703bf8f0e 100644
--- a/doc/git-annex-registerurl.mdwn
+++ b/doc/git-annex-registerurl.mdwn
@@ -13,10 +13,6 @@ key can be downloaded from.
 
 No verification is performed of the url's contents.
 
-If no key and url pair are specified on the command line,
-batch input is used, the same as if the --batch option were
-specified.
-
 Normally the key is a git-annex formatted key. However, to make it easier
 to use this to add urls, if the key cannot be parsed as a key, and is a
 valid url, an URL key is constructed from the url.
@@ -28,6 +24,11 @@ valid url, an URL key is constructed from the url.
   In batch input mode, lines are read from stdin, and each line
   should contain a key and url, separated by a single space.
 
+  For backwards compatability with old git-annex before this option
+  was added, when no key and url pair are specified on the command line,
+  batch input is used, the same as if the --batch option were
+  specified. It is however recommended to use --batch.
+
 * `-z`
 
    When in batch mode, the input is delimited by nulls instead of the usual
@@ -42,6 +43,8 @@ valid url, an URL key is constructed from the url.
 
 [[git-annex-addurl]](1)
 
+[[git-annex-unregisterurl]](1)
+
 # AUTHOR
 
 Joey Hess <id@joeyh.name>
diff --git a/doc/git-annex-unregisterurl.mdwn b/doc/git-annex-unregisterurl.mdwn
new file mode 100644
index 000000000..bf582d645
--- /dev/null
+++ b/doc/git-annex-unregisterurl.mdwn
@@ -0,0 +1,41 @@
+# NAME
+
+git-annex unregisterurl - unregisters an url for a key
+
+# SYNOPSIS
+
+git annex unregisterurl `[key url]`
+
+# DESCRIPTION
+
+This plumbing-level command can be used to unregister urls when keys can
+no longer be downloaded from them.
+
+Unregistering a key's last url will make git-annex no longer treat content
+as being present in the web special remote.
+
+# OPTIONS

(Diff truncated)
comment
diff --git a/doc/todo/unregisterurl_KEY_URL/comment_3_22edc4e69a686511c76c7c7608da5793._comment b/doc/todo/unregisterurl_KEY_URL/comment_3_22edc4e69a686511c76c7c7608da5793._comment
new file mode 100644
index 000000000..bc381ba00
--- /dev/null
+++ b/doc/todo/unregisterurl_KEY_URL/comment_3_22edc4e69a686511c76c7c7608da5793._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 3"""
+ date="2021-03-01T17:39:31Z"
+ content="""
+After using setpresentkey git-annex still has the url
+registered and a later addurl of a new url would make git-annex also
+start trying the old url. Also, if there are several urls, you might only
+want to remove one, not remove it from the web special remote entirely
+as setpresentkey does.
+
+`rmurl --key` would be fine until a batch version was wanted, and then
+something would need to be done about [[todo/git-annex-get_--batch_--key]].
+Which would be good to solve generally somehow, but otoh, `git-annex
+unregisterurl` neatly avoids that more general problem. Also, it makes
+sense that a registerurl user would look for a dual command like
+unregisterurl before looking in rmurl for a way to do it.
+
+So I think unregisterurl is the right thing to add.
+"""]]

analysis
diff --git a/doc/bugs/find_--batch_reports_files_that_have_no_content/comment_1_d0dcd56a0af59bb53092c518a4e3eefd._comment b/doc/bugs/find_--batch_reports_files_that_have_no_content/comment_1_d0dcd56a0af59bb53092c518a4e3eefd._comment
new file mode 100644
index 000000000..13fc0e337
--- /dev/null
+++ b/doc/bugs/find_--batch_reports_files_that_have_no_content/comment_1_d0dcd56a0af59bb53092c518a4e3eefd._comment
@@ -0,0 +1,21 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 1"""
+ date="2021-03-01T17:10:45Z"
+ content="""
+The problem is that withKeyOptions' runbranchkeys finds keys,
+and matchLockStatus with a MatchingKey is always False. The former would
+need to check if the file in the branch is unlocked or not and add that to
+the data for use by the latter.
+
+Looks like it can be done without adding any additional overhead,
+but currently catKey reads the git ref and uses parseLinkTargetOrPointer
+which handles both indiscriminitely, so that would also need to be changed.
+
+This goes beyond find, the same basic problem is that
+`git-annex whereis --unlocked --all` does not display anything,
+while without the --unlocked it does. Probably it should not be allowed
+to combine --unlocked and --locked with --all or --key, because that does
+not actually make any sense. Also --all with
+--include/--exclude/--want-get/--want-drop/--mimetype/--mimeencoding.
+"""]]

fix problem with example
diff --git a/doc/git-annex-unlock.mdwn b/doc/git-annex-unlock.mdwn
index b410c880b..9b5051fb5 100644
--- a/doc/git-annex-unlock.mdwn
+++ b/doc/git-annex-unlock.mdwn
@@ -39,6 +39,7 @@ repository. So, enable annex.thin with care.
 
 	# git annex unlock photo.jpg
 	# gimp photo.jpg
+	# git annex add photo.jpg
 	# git annex lock photo.jpg
 	# git commit -m "redeye removal"
 
diff --git a/doc/git-annex-unlock/comment_6_7ab5b674d0fc18da262e6c0264953e21._comment b/doc/git-annex-unlock/comment_6_7ab5b674d0fc18da262e6c0264953e21._comment
new file mode 100644
index 000000000..ec3e10f15
--- /dev/null
+++ b/doc/git-annex-unlock/comment_6_7ab5b674d0fc18da262e6c0264953e21._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""re: issue with example"""
+ date="2021-03-01T17:07:06Z"
+ content="""
+`git-annex lock` wouldn't erase any modifications, but it would fail
+due to the file being modified. Fixed the example to use `git-annex add`
+before locking.
+"""]]

Added a comment: issue of pushing refs to annexed files but not info on how to fetch them
diff --git a/doc/todo/option_to_block_git_from_pushing_references_to_not-yet-saved_contents/comment_3_7337c487d7118e0bfdf931a741f3d5a4._comment b/doc/todo/option_to_block_git_from_pushing_references_to_not-yet-saved_contents/comment_3_7337c487d7118e0bfdf931a741f3d5a4._comment
new file mode 100644
index 000000000..ec912940a
--- /dev/null
+++ b/doc/todo/option_to_block_git_from_pushing_references_to_not-yet-saved_contents/comment_3_7337c487d7118e0bfdf931a741f3d5a4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="Ilya_Shlyakhter"
+ avatar="http://cdn.libravatar.org/avatar/1647044369aa7747829c38b9dcc84df0"
+ subject="issue of pushing refs to annexed files but not info on how to fetch them"
+ date="2021-03-01T16:46:56Z"
+ content="""
+Just got burned by a (variation of) this issue, after coming back to git-annex after a break. This time, I did `git-annex-copy` the files to a remote, but forgot to `git-annex-sync` the new location information, so a new clone could not access the files.   Maybe, a [pre-push hook](https://git-scm.com/docs/githooks#_pre_push) could be installed to print a warning (that can be turned off by a config setting), whenever you push refs to annexed files to a remote that has no (semi-)trusted location information for them?  Basically, as a git user you get used to thinking that `git push` saves your work, and forgetting that it doesn't with `git-annex` can lead to data loss/inaccessibility.
+"""]]

Added a comment: issue with example
diff --git a/doc/git-annex-unlock/comment_6_047355b1ba5e90b71fc85b42f52d1aeb._comment b/doc/git-annex-unlock/comment_6_047355b1ba5e90b71fc85b42f52d1aeb._comment
new file mode 100644
index 000000000..182b05f5c
--- /dev/null
+++ b/doc/git-annex-unlock/comment_6_047355b1ba5e90b71fc85b42f52d1aeb._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="Ilya_Shlyakhter"
+ avatar="http://cdn.libravatar.org/avatar/1647044369aa7747829c38b9dcc84df0"
+ subject="issue with example"
+ date="2021-02-28T23:18:26Z"
+ content="""
+In the example, wouldn't `git-annex-unlock` erase any edits made in gimp? Was this meant to use `git-annex-add` instead?
+
+# EXAMPLES
+
+	# git annex unlock photo.jpg
+	# gimp photo.jpg
+	# git annex lock photo.jpg
+	# git commit -m \"redeye removal\"
+
+"""]]

annex-review-unused -> git annex reviewunused
diff --git a/doc/related_software.mdwn b/doc/related_software.mdwn
index 551908e94..8dd1c24b0 100644
--- a/doc/related_software.mdwn
+++ b/doc/related_software.mdwn
@@ -55,6 +55,6 @@ designed to interoperate with it.
 
 * [AnnexRemote](https://github.com/Lykos153/AnnexRemote) is a python library for creating new external special remotes.
 
-* [Git::Annex](https://metacpan.org/release/Git-Annex) is a Perl interface to git-annex, including a script `annex-review-unused` for interactively processing git-annex-unused output
+* [Git::Annex](https://metacpan.org/release/Git-Annex) is a Perl interface to git-annex, including a script `git annex reviewunused` for interactively processing git-annex-unused output
 
 See also [[not]] for software that is *not* related to git-annex, but similar.

removed
diff --git a/doc/forum/Did_uninit_lose_file_contents__63__.mdwn b/doc/forum/Did_uninit_lose_file_contents__63__.mdwn
deleted file mode 100644
index 83e79b230..000000000
--- a/doc/forum/Did_uninit_lose_file_contents__63__.mdwn
+++ /dev/null
@@ -1,72 +0,0 @@
-I seem to have lost the contents of some files after running `git annex uninit`, and I'm not sure where I went wrong.
-
-Here is what I think I did, in order:
-
-- Create annex - `git init && git annex init`.
-
-- Set thin mode - `git config annex.thin true && git annex fix`.
-
-- Set largefiles size - `git config annex.largefiles anything`.
-
-- Set addunlocked - `git config annex.addunlocked true`.
-
-- Added all files - `git annex add` (~135,000 files, ~350GiB).
-
-- Cloned the repo to a couple of other locations (one bare git repo, and one NTFS hard drive), and added them as remotes of one another.
-
-- Created adjusted branches (hidemissing and unlocked).
-
-- Did git-annexy things between the repos, ie. `sync`, `get`, `move`, `drop`, `whereis` (these all worked fine).
-
-Then I ran `git annex uninit` and it seemed to start OK (there was output that looked like it was moving files out of the annex), so I left it running overnight. This morning it was still running, but every file it seemed to be processing was displaying errors like this:
-
-```
-error: path/to/file1.mp3: cannot add to the index - missing --add option?
-fatal: Unable to process path path/to/file1.mp3
-(recording state in git...)
-error: path/to/file2.mp3: cannot add to the index - missing --add option?
-fatal: Unable to process path path/to/file2.mp3
-(recording state in git...)
-```
-
-I stopped it with Ctrl-C, and ran `git annex uninit` again. The command ran for a few seconds, and then finished with this output:
-
-```
-Deleted branch git-annex (was f08b3b7c92).
-```
-
-Looking at the contents of one of these files, it looks like the content should still be in the annex?
-
-```
-$ cat "path/to/file1.mp3"
-/annex/objects/SHA256E-s8540947--baaf8e92ad996686bb4e507954ee014c8f43b9e4c5f19d524b6305f2a967d255.mp3
-```
-
-But the annex is gone!?
-
-```
-$ ls .git/annex/
-ls: cannot access '.git/annex/': No such file or directory
-```
-
-So I'm wondering two things:
-
-1. Is there any way to get the contents of these files back (without using the cloned repos or backups in other locations)?
-
-2. Did the contents of these files get removed from the annex without the original files being restored? If so, why?
-
---
-
-git-annex details:
-
-```
-$ git-annex version
-git-annex version: 8.20200810
-build flags: Assistant Webapp Pairing S3 WebDAV Inotify DBus DesktopNotify TorrentParser MagicMime Feeds Testsuite
-dependency versions: aws-0.22 bloomfilter-2.0.1.0 cryptonite-0.27 DAV-1.3.4 feed-1.3.0.1 ghc-8.8.4 http-client-0.6.4.1 persistent-sqlite-2.10.6.2 torrent-10000.1.1 uuid-1.3.13 yesod-1.6.1.0
-key/value backends: SHA256E SHA256 SHA512E SHA512 SHA224E SHA224 SHA384E SHA384 SHA3_256E SHA3_256 SHA3_512E SHA3_512 SHA3_224E SHA3_224 SHA3_384E SHA3_384 SKEIN256E SKEIN256 SKEIN512E SKEIN512 BLAKE2B256E BLAKE2B256 BLAKE2B512E BLAKE2B512 BLAKE2B160E BLAKE2B160 BLAKE2B224E BLAKE2B224 BLAKE2B384E BLAKE2B384 BLAKE2BP512E BLAKE2BP512 BLAKE2S256E BLAKE2S256 BLAKE2S160E BLAKE2S160 BLAKE2S224E BLAKE2S224 BLAKE2SP256E BLAKE2SP256 BLAKE2SP224E BLAKE2SP224 SHA1E SHA1 MD5E MD5 WORM URL X*
-remote types: git gcrypt p2p S3 bup directory rsync web bittorrent webdav adb tahoe glacier ddar git-lfs hook external
-operating system: linux x86_64
-supported repository versions: 8
-upgrade supported from repository versions: 0 1 2 3 4 5 6 7
-```

diff --git a/doc/forum/Did_uninit_lose_file_contents__63__.mdwn b/doc/forum/Did_uninit_lose_file_contents__63__.mdwn
index 5993bcb1d..83e79b230 100644
--- a/doc/forum/Did_uninit_lose_file_contents__63__.mdwn
+++ b/doc/forum/Did_uninit_lose_file_contents__63__.mdwn
@@ -14,7 +14,7 @@ Here is what I think I did, in order:
 
 - Cloned the repo to a couple of other locations (one bare git repo, and one NTFS hard drive), and added them as remotes of one another.
 
-- Created an adjusted branch (hidemissing).
+- Created adjusted branches (hidemissing and unlocked).
 
 - Did git-annexy things between the repos, ie. `sync`, `get`, `move`, `drop`, `whereis` (these all worked fine).
 

diff --git a/doc/forum/Did_uninit_lose_file_contents__63__.mdwn b/doc/forum/Did_uninit_lose_file_contents__63__.mdwn
new file mode 100644
index 000000000..5993bcb1d
--- /dev/null
+++ b/doc/forum/Did_uninit_lose_file_contents__63__.mdwn
@@ -0,0 +1,72 @@
+I seem to have lost the contents of some files after running `git annex uninit`, and I'm not sure where I went wrong.
+
+Here is what I think I did, in order:
+
+- Create annex - `git init && git annex init`.
+
+- Set thin mode - `git config annex.thin true && git annex fix`.
+
+- Set largefiles size - `git config annex.largefiles anything`.
+
+- Set addunlocked - `git config annex.addunlocked true`.
+
+- Added all files - `git annex add` (~135,000 files, ~350GiB).
+
+- Cloned the repo to a couple of other locations (one bare git repo, and one NTFS hard drive), and added them as remotes of one another.
+
+- Created an adjusted branch (hidemissing).
+
+- Did git-annexy things between the repos, ie. `sync`, `get`, `move`, `drop`, `whereis` (these all worked fine).
+
+Then I ran `git annex uninit` and it seemed to start OK (there was output that looked like it was moving files out of the annex), so I left it running overnight. This morning it was still running, but every file it seemed to be processing was displaying errors like this:
+
+```
+error: path/to/file1.mp3: cannot add to the index - missing --add option?
+fatal: Unable to process path path/to/file1.mp3
+(recording state in git...)
+error: path/to/file2.mp3: cannot add to the index - missing --add option?
+fatal: Unable to process path path/to/file2.mp3
+(recording state in git...)
+```
+
+I stopped it with Ctrl-C, and ran `git annex uninit` again. The command ran for a few seconds, and then finished with this output:
+
+```
+Deleted branch git-annex (was f08b3b7c92).
+```
+
+Looking at the contents of one of these files, it looks like the content should still be in the annex?
+
+```
+$ cat "path/to/file1.mp3"
+/annex/objects/SHA256E-s8540947--baaf8e92ad996686bb4e507954ee014c8f43b9e4c5f19d524b6305f2a967d255.mp3
+```
+
+But the annex is gone!?
+
+```
+$ ls .git/annex/
+ls: cannot access '.git/annex/': No such file or directory
+```
+
+So I'm wondering two things:
+
+1. Is there any way to get the contents of these files back (without using the cloned repos or backups in other locations)?
+
+2. Did the contents of these files get removed from the annex without the original files being restored? If so, why?
+
+--
+
+git-annex details:
+
+```
+$ git-annex version
+git-annex version: 8.20200810
+build flags: Assistant Webapp Pairing S3 WebDAV Inotify DBus DesktopNotify TorrentParser MagicMime Feeds Testsuite
+dependency versions: aws-0.22 bloomfilter-2.0.1.0 cryptonite-0.27 DAV-1.3.4 feed-1.3.0.1 ghc-8.8.4 http-client-0.6.4.1 persistent-sqlite-2.10.6.2 torrent-10000.1.1 uuid-1.3.13 yesod-1.6.1.0
+key/value backends: SHA256E SHA256 SHA512E SHA512 SHA224E SHA224 SHA384E SHA384 SHA3_256E SHA3_256 SHA3_512E SHA3_512 SHA3_224E SHA3_224 SHA3_384E SHA3_384 SKEIN256E SKEIN256 SKEIN512E SKEIN512 BLAKE2B256E BLAKE2B256 BLAKE2B512E BLAKE2B512 BLAKE2B160E BLAKE2B160 BLAKE2B224E BLAKE2B224 BLAKE2B384E BLAKE2B384 BLAKE2BP512E BLAKE2BP512 BLAKE2S256E BLAKE2S256 BLAKE2S160E BLAKE2S160 BLAKE2S224E BLAKE2S224 BLAKE2SP256E BLAKE2SP256 BLAKE2SP224E BLAKE2SP224 SHA1E SHA1 MD5E MD5 WORM URL X*
+remote types: git gcrypt p2p S3 bup directory rsync web bittorrent webdav adb tahoe glacier ddar git-lfs hook external
+operating system: linux x86_64
+supported repository versions: 8
+upgrade supported from repository versions: 0 1 2 3 4 5 6 7
+```

todo
diff --git a/doc/todo/timeout_support_for_importfeed.mdwn b/doc/todo/timeout_support_for_importfeed.mdwn
new file mode 100644
index 000000000..f89da8d2e
--- /dev/null
+++ b/doc/todo/timeout_support_for_importfeed.mdwn
@@ -0,0 +1,7 @@
+I have a git-annex importfeed of a bunch of podcasts that sometimes seems to
+get stalled and hang forever on one of them.
+
+It should be possible to time out the http requests in importfeed. Or even
+move the work into git-annex transferrer like has been done for transfers.
+Configurable by annex.stalldetection..
+--[[Joey]]

Added a comment
diff --git a/doc/bugs/openTempFile/comment_3_9b9f35c8ed31ca62b34d216c6906304c._comment b/doc/bugs/openTempFile/comment_3_9b9f35c8ed31ca62b34d216c6906304c._comment
new file mode 100644
index 000000000..b07bbf667
--- /dev/null
+++ b/doc/bugs/openTempFile/comment_3_9b9f35c8ed31ca62b34d216c6906304c._comment
@@ -0,0 +1,22 @@
+[[!comment format=mdwn
+ username="arelius@a7e47ae13cb3452464261e3a99bfe6d2c25895fd"
+ nickname="arelius"
+ avatar="http://cdn.libravatar.org/avatar/f89b3d8d61a90fed8f52ac7ea9dd4456"
+ subject="comment 3"
+ date="2021-02-25T21:46:20Z"
+ content="""
+Yeah, this is only happening on the network share.
+
+The Network share does have a .git/hooks/ already.
+
+To add more info, I also tried to create a specialremote on the same network share:
+
+git annex initremote pudelvault type=directory directory=//pudelvault/project/annextestspecialremote/ encryption=none
+
+and when I try to sync content with it with:
+git annex sync --content
+
+I get a long list of somewhat similar errors:
+//pudelvault/project/annextestspecialremote\tmp\SHA256E-s5930--76c659680c2488528a0efbf315f52781df2fe3082e2cd87db87ebe487c3d85e5.hx\SHA256E-s5930--76c659680c2488528a0efbf315f52781df2fe3082e2cd87db87ebe487c3d85e5.hx: openBinaryFile: does not exist (No such file or directory)
+failed
+"""]]

Added a comment
diff --git a/doc/todo/unregisterurl_KEY_URL/comment_2_87ec9a2037eaa84011f7e7ecf43d31aa._comment b/doc/todo/unregisterurl_KEY_URL/comment_2_87ec9a2037eaa84011f7e7ecf43d31aa._comment
new file mode 100644
index 000000000..71cce2db4
--- /dev/null
+++ b/doc/todo/unregisterurl_KEY_URL/comment_2_87ec9a2037eaa84011f7e7ecf43d31aa._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="kyle"
+ avatar="http://cdn.libravatar.org/avatar/7d6e85cde1422ad60607c87fa87c63f3"
+ subject="comment 2"
+ date="2021-02-25T21:25:51Z"
+ content="""
+I said:
+
+> I think you could use setpresentkey.
+
+Never mind, I don't think that's a good idea, since it's not operating
+on a particular URL and adjusting the log.web file.
+"""]]

Added a comment: setpresentkey 0
diff --git a/doc/todo/unregisterurl_KEY_URL/comment_1_9562b4583203b49ec68162f3a4816ad7._comment b/doc/todo/unregisterurl_KEY_URL/comment_1_9562b4583203b49ec68162f3a4816ad7._comment
new file mode 100644
index 000000000..26e989a04
--- /dev/null
+++ b/doc/todo/unregisterurl_KEY_URL/comment_1_9562b4583203b49ec68162f3a4816ad7._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="kyle"
+ avatar="http://cdn.libravatar.org/avatar/7d6e85cde1422ad60607c87fa87c63f3"
+ subject="setpresentkey 0"
+ date="2021-02-25T21:18:48Z"
+ content="""
+Fwiw adding `--key` to `rmurl` sounds nice to me, and, since it looks
+like RmUrl.hs already maps from file to key, I'd guess that be a
+natural addition.
+
+> I have not found how could it be possibly done ATM without direct
+> editing of .web files in the git-annex branch.
+
+I think you could use `setpresentkey`.  So for a plain web URL:
+
+```
+git annex setpresentkey $key 00000000-0000-0000-0000-000000000001 0
+```
+
+"""]]

or just a rmurl --key?
diff --git a/doc/todo/unregisterurl_KEY_URL.mdwn b/doc/todo/unregisterurl_KEY_URL.mdwn
index 627def2e4..b4df00d78 100644
--- a/doc/todo/unregisterurl_KEY_URL.mdwn
+++ b/doc/todo/unregisterurl_KEY_URL.mdwn
@@ -11,5 +11,7 @@ git-annex version: 8.20210223-1~ndall+1
 
 So ATM there is addurl/rmurl when operating on a FILE, and there is `registerurl` when operating on a KEY, but there seems to be no way to `unregisterurl` as to `rmurl` from a KEY.  I have not found how could it be possibly done ATM without direct editing of .web files in the git-annex branch.
 
+edit 1: well, instead of adding `unregisterurl` could be done by adding `--key` flag to `rmurl` I think.
+
 [[!meta author=yoh]]
 [[!tag projects/dandi]]

TODO for unregisterurl
diff --git a/doc/todo/unregisterurl_KEY_URL.mdwn b/doc/todo/unregisterurl_KEY_URL.mdwn
new file mode 100644
index 000000000..627def2e4
--- /dev/null
+++ b/doc/todo/unregisterurl_KEY_URL.mdwn
@@ -0,0 +1,15 @@
+```
+$> git annex --mumba 2>&1 | grep -e url 
+  addurl          URL ...                   add urls to annex
+  rmurl           FILE URL ...              record file is not available at url
+  registerurl     KEY URL                   registers an url for a key
+
+$> git annex version | head -n 1
+git-annex version: 8.20210223-1~ndall+1
+
+```
+
+So ATM there is addurl/rmurl when operating on a FILE, and there is `registerurl` when operating on a KEY, but there seems to be no way to `unregisterurl` as to `rmurl` from a KEY.  I have not found how could it be possibly done ATM without direct editing of .web files in the git-annex branch.
+
+[[!meta author=yoh]]
+[[!tag projects/dandi]]

diff --git a/doc/bugs/find_--branch__58___no_results_with_--__123__un__44____125__locked.mdwn b/doc/bugs/find_--branch__58___no_results_with_--__123__un__44____125__locked.mdwn
new file mode 100644
index 000000000..9e56e2043
--- /dev/null
+++ b/doc/bugs/find_--branch__58___no_results_with_--__123__un__44____125__locked.mdwn
@@ -0,0 +1,82 @@
+If I'm not mistaken, the `--locked` and `--unlocked` limiting options
+are intended to work with `find --branch`, but that leads to empty
+output in all the cases I've tried.
+
+[[!format sh """
+set -eu
+
+cd "$(mktemp -d "${TMPDIR:-/tmp}"/gx-XXXXXXX)"
+git init
+git annex init
+
+git commit --allow-empty -mc0
+echo a >on-master-locked
+echo b >on-master-unlocked
+git annex add on-master-locked on-master-unlocked
+git annex unlock on-master-unlocked
+git commit -mc1
+
+git checkout -b other HEAD~
+echo c >on-other-locked
+echo d >on-other-unlocked
+git annex add on-other-locked on-other-unlocked
+git annex unlock on-other-unlocked
+git commit -mc2
+
+export PS4='$ '
+set -x
+
+git symbolic-ref --short HEAD
+git annex find
+git annex find --locked
+git annex find --unlocked
+
+git checkout -
+
+git annex find
+git annex find --locked
+git annex find --unlocked
+
+git annex find --branch=other
+git annex find --branch=other --locked
+git annex find --branch=other --unlocked
+"""]]
+
+```
+[...]
+29	$ git symbolic-ref --short HEAD
+30	other
+31	$ git annex find
+32	on-other-locked
+33	on-other-unlocked
+34	$ git annex find --locked
+35	on-other-locked
+36	$ git annex find --unlocked
+37	on-other-unlocked
+38	$ git checkout -
+39	Switched to branch 'master'
+40	$ git annex find
+41	on-master-locked
+42	on-master-unlocked
+43	$ git annex find --locked
+44	on-master-locked
+45	$ git annex find --unlocked
+46	on-master-unlocked
+47	$ git annex find --branch=other
+48	on-other-locked
+49	on-other-unlocked
+50	$ git annex find --branch=other --locked
+51	$ git annex find --branch=other --unlocked
+```
+
+Lines 29-49 show the output I expected.  On the other hand, I thought
+the last two lines, which combine --branch with --locked and
+--unlocked, would show the same output as lines 35 and 37.
+
+I dug a bit hoping I could figure out what was going on, but I haven't
+had any luck so far.
+
+Thanks in advance.
+
+[[!meta author=kyle]]
+[[!tag projects/datalad]]

comment and close not a bug
diff --git a/doc/bugs/not_work__58___Git_annex_addurl_existing_file_without_.mdwn b/doc/bugs/not_work__58___Git_annex_addurl_existing_file_without_.mdwn
index 56f1ac4ac..fabc2ca76 100644
--- a/doc/bugs/not_work__58___Git_annex_addurl_existing_file_without_.mdwn
+++ b/doc/bugs/not_work__58___Git_annex_addurl_existing_file_without_.mdwn
@@ -47,3 +47,4 @@ command line taken from https://git-annex.branchable.com/tips/using_the_web_as_a
 ### Have you had any luck using git-annex before? (Sometimes we get tired of reading bug reports all day and a lil' positive end note does wonders)
 oh, yes, git-annex is great for managing binary files, thanks for the work!
 
+> [[done]], see my comment --[[Joey]]
diff --git a/doc/bugs/not_work__58___Git_annex_addurl_existing_file_without_/comment_1_3958944e36858b97747816c04a0d025a._comment b/doc/bugs/not_work__58___Git_annex_addurl_existing_file_without_/comment_1_3958944e36858b97747816c04a0d025a._comment
new file mode 100644
index 000000000..2d27e787f
--- /dev/null
+++ b/doc/bugs/not_work__58___Git_annex_addurl_existing_file_without_/comment_1_3958944e36858b97747816c04a0d025a._comment
@@ -0,0 +1,24 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 1"""
+ date="2021-02-24T17:20:12Z"
+ content="""
+Well, it makes sense for addurl run on a file that is not an annexed file to
+fail. There is nothing else it could do in that case that makes sense.
+It can't record that the youtube url is a location for the annexed file,
+because there is no annexed file.
+
+What you can do is git-annex addurl --relaxed with the youtube url,
+which does not download it, and then make git-annex treat the mp4 file
+as the content, by running git-annex reinject with the first parameter
+being the git-annex filename, and the second being the f.mp4, which will
+get moved into the annex.
+
+	git-annex addurl --file youtube.vid https://www.youtube.com/watch?v=U33dsEcKge  --relaxed
+	git-annex reinject f.mp4 youtube.vid
+
+Note that this command will work no matter what the content of the first file
+is, it will accept anything due to the use of --relaxed. So it's up to you
+to make sure you use it with a file that's the same content as the youtube
+video.
+"""]]

Windows: Correct the path to the html help file for 64 bit build.
diff --git a/Build/NullSoftInstaller.hs b/Build/NullSoftInstaller.hs
index 973359221..ca209076d 100644
--- a/Build/NullSoftInstaller.hs
+++ b/Build/NullSoftInstaller.hs
@@ -190,8 +190,8 @@ makeInstaller gitannex gitannexcmd license htmlhelp extrabins sharefiles launche
 		addfile gitannexcmd
 	section "meta" [] $ do
 		-- git opens this file when git annex --help is run.
-		-- (Program Files/Git/mingw32/share/doc/git-doc/git-annex.html)
-		setOutPath "$INSTDIR\\mingw32\\share\\doc\\git-doc"
+		-- (Program Files/Git/mingw64/share/doc/git-doc/git-annex.html)
+		setOutPath "$INSTDIR\\mingw64\\share\\doc\\git-doc"
 		addfile htmlhelp
 		setOutPath "$INSTDIR"
 		addfile license
@@ -203,7 +203,7 @@ makeInstaller gitannex gitannexcmd license htmlhelp extrabins sharefiles launche
 		delete [RebootOK] $ autoStartItem
 		removefilesFrom "$INSTDIR/usr/bin" (gitannex:extrabins)
 		removefilesFrom "$INSTDIR/cmd" (gitannexcmd:launchers)
-		removefilesFrom "$INSTDIR\\mingw32\\share\\doc\\git-doc" [htmlhelp]
+		removefilesFrom "$INSTDIR\\mingw64\\share\\doc\\git-doc" [htmlhelp]
 		removefilesFrom "$INSTDIR" [license, uninstaller]
   where
 	addfile f = file [] (str f)
diff --git a/CHANGELOG b/CHANGELOG
index 973bc42ad..d7767bd38 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,9 @@
+git-annex (8.20210224) UNRELEASED; urgency=medium
+
+  * Windows: Correct the path to the html help file for 64 bit build.
+
+ -- Joey Hess <id@joeyh.name>  Wed, 24 Feb 2021 13:18:38 -0400
+
 git-annex (8.20210223) upstream; urgency=medium
 
   * annex.stalldetection can now be set to "true" to make git-annex
diff --git a/doc/install/Windows/comment_18_e0adfbf74754f847dc4705685cf00640._comment b/doc/install/Windows/comment_18_e0adfbf74754f847dc4705685cf00640._comment
new file mode 100644
index 000000000..845d50be1
--- /dev/null
+++ b/doc/install/Windows/comment_18_e0adfbf74754f847dc4705685cf00640._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""re: comment 17"""
+ date="2021-02-24T17:18:01Z"
+ content="""
+I've corrected that path.
+
+(Please don't use this page to report issues with the windows build.
+Open bug reports.)
+"""]]

retitle
diff --git a/doc/bugs/openTempFile.mdwn b/doc/bugs/openTempFile.mdwn
index 1028006d7..c3f7ff1fb 100644
--- a/doc/bugs/openTempFile.mdwn
+++ b/doc/bugs/openTempFile.mdwn
@@ -55,3 +55,5 @@ upgrade supported from repository versions: 2 3 4 5 6 7
 ### Have you had any luck using git-annex before? (Sometimes we get tired of reading bug reports all day and a lil' positive end note does wonders)
 
 Work without problem on local drive.
+
+[[!meta title="Windows: .git\\hooks: openTempFile: does not exist"]]

comment
diff --git a/doc/bugs/openTempFile/comment_2_a09c4a7d346c3b0f7025e6f3a276adb8._comment b/doc/bugs/openTempFile/comment_2_a09c4a7d346c3b0f7025e6f3a276adb8._comment
new file mode 100644
index 000000000..5c21c147f
--- /dev/null
+++ b/doc/bugs/openTempFile/comment_2_a09c4a7d346c3b0f7025e6f3a276adb8._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 2"""
+ date="2021-02-24T17:13:43Z"
+ content="""
+Does this only happen when the directory is on the network share, or also
+on a local disk?
+
+Does the .git/hooks directory exist? What happens if you mkdir that
+directory and then re-run git-annex init?
+
+This does not seem to happen on windows generally, and git-annex creates
+the directory if it does not exist, so failing this way is surprising.
+"""]]

diff --git a/doc/bugs/not_work__58___Git_annex_addurl_existing_file_without_.mdwn b/doc/bugs/not_work__58___Git_annex_addurl_existing_file_without_.mdwn
new file mode 100644
index 000000000..56f1ac4ac
--- /dev/null
+++ b/doc/bugs/not_work__58___Git_annex_addurl_existing_file_without_.mdwn
@@ -0,0 +1,49 @@
+### Please describe the problem.
+not work: Git annex addurl existing file without redownloading, use URL-backend (not any hashkey-backend)
+
+### What steps will reproduce the problem?
+File copied to git (git-annex) repo's dir  (did not 'git add' 'git annex add')
+name: 'f.mp4'
+Now run 'git annex addurl --file=f.mp4 --raw --relaxed https://www.youtube.com/watch?v=U33dsEcKge ' (via Python, see below)
+
+RESULT:
+failed "f.mp4 already exists; not overwriting"
+
+(same if run in Python)
+File "/opt/anaconda3/lib/python3.7/subprocess.py", line 512, in run
+    output=stdout, stderr=stderr)
+subprocess.CalledProcessError: Command '['git', 'annex', 'addurl', '--file=f.mp4', '--raw', '--relaxed', 'https://www.youtube.com/watch?v=U33dsEcKgeQ']' returned non-zero exit status 1.
+
+Above command would work after doing 'git annex add f.mp4' first
+  but it results in a backend not 'URL backend for youtube'
+  I'd like to use 'URL backend for youtube' cause I worry about youtube-video binay-change, in which case all future download will fail backend verification.
+
+
+
+### What version of git-annex are you using? On what operating system?
+macOS 10.14.6, installed by 'brew install git-annex'
+git annex version
+git-annex version: 8.20201129
+build flags: Assistant Webapp Pairing FsEvents TorrentParser MagicMime Feeds Testsuite S3 WebDAV
+dependency versions: aws-0.22 bloomfilter-2.0.1.0 cryptonite-0.27 DAV-1.3.4 feed-1.3.0.1 ghc-8.10.3 http-client-0.7.3 persistent-sqlite-2.11.0.0 torrent-10000.1.1 uuid-1.3.13 yesod-1.6.1.0
+key/value backends: SHA256E SHA256 SHA512E SHA512 SHA224E SHA224 SHA384E SHA384 SHA3_256E SHA3_256 SHA3_512E SHA3_512 SHA3_224E SHA3_224 SHA3_384E SHA3_384 SKEIN256E SKEIN256 SKEIN512E SKEIN512 BLAKE2B256E BLAKE2B256 BLAKE2B512E BLAKE2B512 BLAKE2B160E BLAKE2B160 BLAKE2B224E BLAKE2B224 BLAKE2B384E BLAKE2B384 BLAKE2BP512E BLAKE2BP512 BLAKE2S256E BLAKE2S256 BLAKE2S160E BLAKE2S160 BLAKE2S224E BLAKE2S224 BLAKE2SP256E BLAKE2SP256 BLAKE2SP224E BLAKE2SP224 SHA1E SHA1 MD5E MD5 WORM URL X*
+remote types: git gcrypt p2p S3 bup directory rsync web bittorrent webdav adb tahoe glacier ddar git-lfs httpalso borg hook external
+operating system: darwin x86_64
+supported repository versions: 8
+upgrade supported from repository versions: 0 1 2 3 4 5 6 7
+
+
+### Please provide any additional information below.
+command line taken from https://git-annex.branchable.com/tips/using_the_web_as_a_special_remote/
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
+
+### Have you had any luck using git-annex before? (Sometimes we get tired of reading bug reports all day and a lil' positive end note does wonders)
+oh, yes, git-annex is great for managing binary files, thanks for the work!
+

diff --git a/doc/bugs/openTempFile.mdwn b/doc/bugs/openTempFile.mdwn
index d93a54c0b..1028006d7 100644
--- a/doc/bugs/openTempFile.mdwn
+++ b/doc/bugs/openTempFile.mdwn
@@ -11,6 +11,7 @@ git init
 
 git annex init, observe output:
 
+[[!format sh """
 Microsoft.PowerShell.Core\FileSystem::\\pudelvault\project\annextest❯ git annex init "pudelvault"
 init pudelvault
   Detected a filesystem without fifo support.
@@ -22,13 +23,14 @@ init pudelvault
 git-annex: .git\hooks\: openTempFile: does not exist (No such file or directory)
 failed
 git-annex: init: 1 failed
-
+"""]]
 
 ### What version of git-annex are you using? On what operating system?
 Windows 10
 
 git version 2.30.1.windows.1
 
+[[!format sh """
 git-annex version: 8.20210128-g4407ade4c
 build flags: Assistant Webapp Pairing TorrentParser MagicMime Feeds Testsuite S3 WebDAV
 dependency versions: aws-0.22 bloomfilter-2.0.1.0 cryptonite-0.26 DAV-1.3.4 feed-1.3.0.1 ghc-8.8.4 http-client-0.6.4.1 persistent-sqlite-2.10.6.2 torrent-10000.1.1 uuid-1.3.13 yesod-1.6.1.0
@@ -37,6 +39,7 @@ remote types: git gcrypt p2p S3 bup directory rsync web bittorrent webdav adb ta
 operating system: mingw32 x86_64
 supported repository versions: 8
 upgrade supported from repository versions: 2 3 4 5 6 7
+"""]]
 
 
 ### Please provide any additional information below.

Added a comment
diff --git a/doc/install/Windows/comment_17_165ac8b0e1cd4f250e681eb88c0624d3._comment b/doc/install/Windows/comment_17_165ac8b0e1cd4f250e681eb88c0624d3._comment
new file mode 100644
index 000000000..5036ee9ef
--- /dev/null
+++ b/doc/install/Windows/comment_17_165ac8b0e1cd4f250e681eb88c0624d3._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="arelius@a7e47ae13cb3452464261e3a99bfe6d2c25895fd"
+ nickname="arelius"
+ avatar="http://cdn.libravatar.org/avatar/f89b3d8d61a90fed8f52ac7ea9dd4456"
+ subject="comment 17"
+ date="2021-02-24T04:49:33Z"
+ content="""
+I'm using the git-annex from the CI build... Even though it appears to be an x64 build, it appears to put the docs in /mingw32 instead of /mingw64 preventing the docs from being located.
+"""]]

Added a comment
diff --git a/doc/bugs/openTempFile/comment_1_48b9ab6e3d4b24ec34d2a99b5a4ff619._comment b/doc/bugs/openTempFile/comment_1_48b9ab6e3d4b24ec34d2a99b5a4ff619._comment
new file mode 100644
index 000000000..cc0ae530c
--- /dev/null
+++ b/doc/bugs/openTempFile/comment_1_48b9ab6e3d4b24ec34d2a99b5a4ff619._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="arelius@a7e47ae13cb3452464261e3a99bfe6d2c25895fd"
+ nickname="arelius"
+ avatar="http://cdn.libravatar.org/avatar/f89b3d8d61a90fed8f52ac7ea9dd4456"
+ subject="comment 1"
+ date="2021-02-24T04:32:05Z"
+ content="""
+Sorry for the page URL, wasn't clear that I was creating a bug with that name.
+"""]]

diff --git a/doc/bugs/openTempFile.mdwn b/doc/bugs/openTempFile.mdwn
new file mode 100644
index 000000000..d93a54c0b
--- /dev/null
+++ b/doc/bugs/openTempFile.mdwn
@@ -0,0 +1,54 @@
+### Please describe the problem.
+On Windows, failure trying to initialize a remote repository over a Samba share.
+
+### What steps will reproduce the problem?
+
+On Windows:
+
+go to a new directory on a network share.
+
+git init
+
+git annex init, observe output:
+
+Microsoft.PowerShell.Core\FileSystem::\\pudelvault\project\annextest❯ git annex init "pudelvault"
+init pudelvault
+  Detected a filesystem without fifo support.
+
+  Disabling ssh connection caching.
+
+  Detected a crippled filesystem.
+
+git-annex: .git\hooks\: openTempFile: does not exist (No such file or directory)
+failed
+git-annex: init: 1 failed
+
+
+### What version of git-annex are you using? On what operating system?
+Windows 10
+
+git version 2.30.1.windows.1
+
+git-annex version: 8.20210128-g4407ade4c
+build flags: Assistant Webapp Pairing TorrentParser MagicMime Feeds Testsuite S3 WebDAV
+dependency versions: aws-0.22 bloomfilter-2.0.1.0 cryptonite-0.26 DAV-1.3.4 feed-1.3.0.1 ghc-8.8.4 http-client-0.6.4.1 persistent-sqlite-2.10.6.2 torrent-10000.1.1 uuid-1.3.13 yesod-1.6.1.0
+key/value backends: SHA256E SHA256 SHA512E SHA512 SHA224E SHA224 SHA384E SHA384 SHA3_256E SHA3_256 SHA3_512E SHA3_512 SHA3_224E SHA3_224 SHA3_384E SHA3_384 SKEIN256E SKEIN256 SKEIN512E SKEIN512 BLAKE2B256E BLAKE2B256 BLAKE2B512E BLAKE2B512 BLAKE2B160E BLAKE2B160 BLAKE2B224E BLAKE2B224 BLAKE2B384E BLAKE2B384 BLAKE2BP512E BLAKE2BP512 BLAKE2S256E BLAKE2S256 BLAKE2S160E BLAKE2S160 BLAKE2S224E BLAKE2S224 BLAKE2SP256E BLAKE2SP256 BLAKE2SP224E BLAKE2SP224 SHA1E SHA1 MD5E MD5 WORM URL X*
+remote types: git gcrypt p2p S3 bup directory rsync web bittorrent webdav adb tahoe glacier ddar git-lfs httpalso borg hook external
+operating system: mingw32 x86_64
+supported repository versions: 8
+upgrade supported from repository versions: 2 3 4 5 6 7
+
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
+
+### Have you had any luck using git-annex before? (Sometimes we get tired of reading bug reports all day and a lil' positive end note does wonders)
+
+Work without problem on local drive.

add news item for git-annex 8.20210223
diff --git a/doc/news/version_8.20201103.mdwn b/doc/news/version_8.20201103.mdwn
deleted file mode 100644
index 96f5a16a5..000000000
--- a/doc/news/version_8.20201103.mdwn
+++ /dev/null
@@ -1,31 +0,0 @@
-git-annex 8.20201103 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-  * move: Improve resuming a move that was interrupted after the object
-    was transferred, in cases where numcopies checks prevented the resumed
-    move from dropping the object from the source repository.
-  * When a special remote has chunking enabled, but no chunk sizes are
-    recorded (or the recorded ones are not found), speculatively try
-    chunks using the configured chunk size.
-  * Fixed some problems that prevented this command from working:
-    git submodule foreach git annex init
-  * Improve shutdown process for external special remotes and external
-    backends. Make sure to relay any remaining stderr from the process,
-    and potentially avoid the process getting a SIGPIPE if it writes to
-    stderr too late.
-  * Fix a bug that prevented linux standalone bundle from working on a fresh
-    install.
-  * Windows build changed to one done by the datalad-extensions project
-    using Github actions.
-  * Windows build now includes libmagic, so mimetype and mimeencoding
-    will work.
-    Thanks to John Thorvald Wodder II and Yaroslav Halchenko for their work
-    on this.
-  * view: Avoid using ':' from metadata when generating a view, because
-    it's a special character on Windows ("c:")
-  * Fix a memory leak introduced in the last release.
-  * add, import: Fix a reversion in 7.20191009 that broke handling
-    of --largerthan and --smallerthan.
-  * view: Fix a reversion in 8.20200522 that broke entering or changing views.
-  * Fix build on Windows with network-3.
-  * testremote: Display exceptions when tests fail, to aid debugging.
-"""]]
diff --git a/doc/news/version_8.20210223.mdwn b/doc/news/version_8.20210223.mdwn
new file mode 100644
index 000000000..5223fb1b4
--- /dev/null
+++ b/doc/news/version_8.20210223.mdwn
@@ -0,0 +1,33 @@
+git-annex 8.20210223 released with [[!toggle text="these changes"]]
+[[!toggleable text="""  * annex.stalldetection can now be set to "true" to make git-annex
+    do automatic stall detection when it detects a remote is updating its
+    transfer progress consistently enough for stall detection to work.
+  * When annex.stalldetection is not enabled and a likely stall is
+    detected, display a suggestion to enable it.
+  * Commands can be added to git-annex, by installing a program in PATH
+    with a name starting with "git-annex-"
+  * Fix a reversion that made import of a tree from a special remote
+    result in a merge that deleted files that were not preferred content
+    of that special remote.
+  * Bugfix: fsck --from a ssh remote did not actually check that the
+    content on the remote is not corrupted.
+  * unannex, uninit: When an annexed file is modified, don't overwrite
+    the modified version with an older version from the annex.
+  * When adding files to an adjusted branch set up by --unlock-present,
+    add them unlocked, not locked.
+  * Fix an oddity in matching options and preferred content expressions
+    such as "foo (bar or baz)", which was incorrectly handled as if
+    it were "(foo or bar) and baz)" rather than the intended
+    "foo and (bar or baz)"
+  * Checksum as content is received from a remote git-annex repository,
+    rather than doing it in a second pass.
+  * Tahoe: Avoid verifying hash after download, since tahoe does sufficient
+    verification itself.
+  * unannex, uninit: Don't run git rm once per annexed file,
+    for a large speedup.
+  * When a git remote is configured with an absolute path, use that
+    path, rather than making it relative.
+  * get: Improve output when failing to get a file fails.
+  * Fix build on openbsd.
+    Thanks, James Cook for the patch.
+  * Include libkqueue.h file needed to build the assistant on BSDs."""]]
\ No newline at end of file

diff --git a/doc/bugs/OSX__58___Pushed_changes_are_autocommited.mdwn b/doc/bugs/OSX__58___Pushed_changes_are_autocommited.mdwn
new file mode 100644
index 000000000..5449ac1e7
--- /dev/null
+++ b/doc/bugs/OSX__58___Pushed_changes_are_autocommited.mdwn
@@ -0,0 +1,88 @@
+### Please describe the problem.
+
+When changes committed in external repos are automatically pushed to a repo residing on OSX via the assistant, the chanes are applied to the repo without the knowledge of the assistant running on the OSX machine or something like that, I can't really explain it.
+
+Example:
+
+If I save a change in a file on Linux, it gets auto-committed and pushed to the OSX machine by the assistant as expected. However, the OSX machine then commits a deletion and re-addition of the file in two separate commits.
+So whenever I save a change, I get a pattern like this:
+
+```
+150ec0dfc * git-annex in MB-<REDACTED>
+29fbe8c12 * git-annex in MB-<REDACTED>
+909a6f30b * git-annex in atemu@HEPHAISTOS:~/Documents
+```
+
+90 are my changes, 29 deletes the file I changed and 15 adds the same file back.  
+As I said, this happens to every change pushed to the OSX machine.
+
+This is especially problematic when merge conflicts arise as it *commits the addition of merge conflict markers*. If that wasn't enough, this is even more problematic when handling unlocked files as those are just plain text files containing paths.
+
+This has often left me with files like these before I gave up and turned off auto-sync:
+
+```
+<<<<<<< HEAD
+/annex/objects/SHA256E-s24532--ce9e93b9ee9f639c916edf5ae07ceb93100718ca039ee9cd2dc6d466074a1c79.org
+=======
+/annex/objects/SHA256E-s24569--f033d710717df25a0082a89266352b95acd6b0b6b170699d5895b335e5f8fcaa.org
+>>>>>>> refs/remotes/10.10.10.18_annex/master
+```
+
+Not fun.
+
+### What steps will reproduce the problem?
+
+1. Assistants running on Linux and OSX machines, syncing with each other
+2. Make a change on the Linux machine
+3. Observe OSX assistant commiting repo changes due to pushed sync
+
+### What version of git-annex are you using? On what operating system?
+
+NixOS Unstable:
+
+https://github.com/Atemu/nixpkgs/tree/637664ff05140d360077c109d9a5bdaf059a47fd
+
+```
+git-annex version: 8.20210127
+build flags: Assistant Webapp Pairing Inotify DBus DesktopNotify TorrentParser MagicMime Feeds Testsuite S3 WebDAV
+dependency versions: aws-0.22 bloomfilter-2.0.1.0 cryptonite-0.27 DAV-1.3.4 feed-1.3.0.1 ghc-8.10.3 http-client-0.6.4.1 persistent-sqlite-2.11.0.0 torrent-10000.1.1 uuid-1.3.13 yesod-1.6.1.0
+key/value backends: SHA256E SHA256 SHA512E SHA512 SHA224E SHA224 SHA384E SHA384 SHA3_256E SHA3_256 SHA3_512E SHA3_512 SHA3_224E SHA3_224 SHA3_384E SHA3_384 SKEIN256E SKEIN256 SKEIN512E SKEIN512 BLAKE2B256E BLAKE2B256 BLAKE2B512E BLAKE2B512 BLAKE2B160E BLAKE2B160 BLAKE2B224E BLAKE2B224 BLAKE2B384E BLAKE2B384 BLAKE2BP512E BLAKE2BP512 BLAKE2S256E BLAKE2S256 BLAKE2S160E BLAKE2S160 BLAKE2S224E BLAKE2S224 BLAKE2SP256E BLAKE2SP256 BLAKE2SP224E BLAKE2SP224 SHA1E SHA1 MD5E MD5 WORM URL X*
+remote types: git gcrypt p2p S3 bup directory rsync web bittorrent webdav adb tahoe glacier ddar git-lfs httpalso borg hook external
+operating system: linux x86_64
+supported repository versions: 8
+upgrade supported from repository versions: 0 1 2 3 4 5 6 7
+local repository version: 8
+```
+
+OSX 10.15.7:
+
+https://github.com/NixOS/nixpkgs/tree/a58a0b5098f0c2a389ee70eb69422a052982d990
+
+```
+git-annex version: 8.20210127
+build flags: Assistant Webapp Pairing FsEvents TorrentParser MagicMime Feeds Testsuite S3 WebDAV
+dependency versions: aws-0.22 bloomfilter-2.0.1.0 cryptonite-0.27 DAV-1.3.4 feed-1.3.0.1 ghc-8.10.3 http-client-0.6.4.1 persistent-sqlite-2.11.0.0 torrent-10000.1.1 uuid-1.3.13 yesod-1.6.1.0
+key/value backends: SHA256E SHA256 SHA512E SHA512 SHA224E SHA224 SHA384E SHA384 SHA3_256E SHA3_256 SHA3_512E SHA3_512 SHA3_224E SHA3_224 SHA3_384E SHA3_384 SKEIN256E SKEIN256 SKEIN512E SKEIN512 BLAKE2B256E BLAKE2B256 BLAKE2B512E BLAKE2B512 BLAKE2B160E BLAKE2B160 BLAKE2B224E BLAKE2B224 BLAKE2B384E BLAKE2B384 BLAKE2BP512E BLAKE2BP512 BLAKE2S256E BLAKE2S256 BLAKE2S160E BLAKE2S160 BLAKE2S224E BLAKE2S224 BLAKE2SP256E BLAKE2SP256 BLAKE2SP224E BLAKE2SP224 SHA1E SHA1 MD5E MD5 WORM URL X*
+remote types: git gcrypt p2p S3 bup directory rsync web bittorrent webdav adb tahoe glacier ddar git-lfs httpalso borg hook external
+operating system: darwin x86_64
+supported repository versions: 8
+upgrade supported from repository versions: 0 1 2 3 4 5 6 7
+local repository version: 8
+```
+
+### Please provide any additional information below.
+
+I use `annex.largefiles=mimeencoding=binary` and text file changes make up the bulk of my commits but the same happens with annexed files as I mentioned.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
+
+### Have you had any luck using git-annex before? (Sometimes we get tired of reading bug reports all day and a lil' positive end note does wonders)
+
+Annex yes, it's amazing; Assistant see frustration above.
+

fix unannex data overwrite bug
unannex, uninit: When an annexed file is modified, don't overwrite the
modified version with an older version from the annex
This commit was sponsored by Mark Reidenbach on Patreon.
diff --git a/CHANGELOG b/CHANGELOG
index cd27e8a44..fc99e6e64 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -28,7 +28,9 @@ git-annex (8.20210128) UNRELEASED; urgency=medium
     rather than doing it in a second pass.
   * Bugfix: fsck --from a ssh remote did not actually check that the
     content on the remote is not corrupted.
-  * unannex, uninit: Avoid running git rm once per annexed file,
+  * unannex, uninit: When an annexed file is modified, don't overwrite
+    the modified version with an older version from the annex.
+  * unannex, uninit: Don't run git rm once per annexed file, 
     for a large speedup.
 
  -- Joey Hess <id@joeyh.name>  Thu, 28 Jan 2021 12:34:32 -0400
diff --git a/Command/Unannex.hs b/Command/Unannex.hs
index 690a946be..94a89f150 100644
--- a/Command/Unannex.hs
+++ b/Command/Unannex.hs
@@ -10,6 +10,7 @@ module Command.Unannex where
 import Command
 import qualified Annex
 import Annex.Perms
+import Annex.Link
 import qualified Annex.Queue
 import Utility.CopyFile
 import qualified Database.Keys
@@ -41,7 +42,6 @@ start si file key =
 
 perform :: RawFilePath -> Key -> CommandPerform
 perform file key = do
-	liftIO $ removeFile (fromRawFilePath file)
 	Annex.Queue.addCommand [] "rm"
 		[ Param "--cached"
 		, Param "--force"
@@ -49,19 +49,34 @@ perform file key = do
 		, Param "--"
 		]
 		[fromRawFilePath file]
-	next $ cleanup file key
+	isAnnexLink file >>= \case
+		-- If the file is locked, it needs to be replaced with
+		-- the content from the annex. Note that it's possible
+		-- for key' (read from the symlink) to differ from key
+		-- (cached in git).
+		Just key' -> do
+			removeassociated
+			next $ cleanup file key'
+		-- If the file is unlocked, it can be unmodified or not and
+		-- does not need to be replaced either way.
+		Nothing -> do
+			removeassociated
+			next $ return True
+  where
+	removeassociated = 
+		Database.Keys.removeAssociatedFile key
+			=<< inRepo (toTopFilePath file)
 
 cleanup :: RawFilePath -> Key -> CommandCleanup
 cleanup file key = do
-	Database.Keys.removeAssociatedFile key =<< inRepo (toTopFilePath file)
+	liftIO $ removeFile (fromRawFilePath file)
 	src <- calcRepo (gitAnnexLocation key)
 	ifM (Annex.getState Annex.fast)
 		( do
 			-- Only make a hard link if the annexed file does not
-			-- already have other hard links pointing at it.
-			-- This avoids unannexing (and uninit) ending up
-			-- hard linking files together, which would be
-			-- surprising.
+			-- already have other hard links pointing at it. This
+			-- avoids unannexing (and uninit) ending up hard
+			-- linking files together, which would be surprising.
 			s <- liftIO $ R.getFileStatus src
 			if linkCount s > 1
 				then copyfrom src
diff --git a/doc/bugs/unannex_of_modified_file_loses_modification.mdwn b/doc/bugs/unannex_of_modified_file_loses_modification.mdwn
index 28a0f1d18..54a6d8119 100644
--- a/doc/bugs/unannex_of_modified_file_loses_modification.mdwn
+++ b/doc/bugs/unannex_of_modified_file_loses_modification.mdwn
@@ -4,3 +4,5 @@ This is a data loss bug.
 
 Command.Unannex.cleanup just overwrites whatever's there without checking.
 Happens with both locked and unlocked files. --[[Joey]]
+
+> [[fixed|done]] --[[Joey]]

bug report
diff --git a/doc/bugs/unannex_of_modified_file_loses_modification.mdwn b/doc/bugs/unannex_of_modified_file_loses_modification.mdwn
new file mode 100644
index 000000000..28a0f1d18
--- /dev/null
+++ b/doc/bugs/unannex_of_modified_file_loses_modification.mdwn
@@ -0,0 +1,6 @@
+git-annex unannex (or uninit) with an annexed file that is modified loses
+the modified version, replacing it with the last annexed version.
+This is a data loss bug.
+
+Command.Unannex.cleanup just overwrites whatever's there without checking.
+Happens with both locked and unlocked files. --[[Joey]]

unannex, uninit: Avoid running git rm once per annexed file, for a large speedup.
diff --git a/CHANGELOG b/CHANGELOG
index 794bc5d71..cd27e8a44 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -28,6 +28,8 @@ git-annex (8.20210128) UNRELEASED; urgency=medium
     rather than doing it in a second pass.
   * Bugfix: fsck --from a ssh remote did not actually check that the
     content on the remote is not corrupted.
+  * unannex, uninit: Avoid running git rm once per annexed file,
+    for a large speedup.
 
  -- Joey Hess <id@joeyh.name>  Thu, 28 Jan 2021 12:34:32 -0400
 
diff --git a/Command/Unannex.hs b/Command/Unannex.hs
index 0b383dd9b..690a946be 100644
--- a/Command/Unannex.hs
+++ b/Command/Unannex.hs
@@ -1,6 +1,6 @@
 {- git-annex command
  -
- - Copyright 2010-2013 Joey Hess <id@joeyh.name>
+ - Copyright 2010-2021 Joey Hess <id@joeyh.name>
  -
  - Licensed under the GNU AGPL version 3 or higher.
  -}
@@ -10,7 +10,7 @@ module Command.Unannex where
 import Command
 import qualified Annex
 import Annex.Perms
-import qualified Git.Command
+import qualified Annex.Queue
 import Utility.CopyFile
 import qualified Database.Keys
 import Git.FilePath
@@ -42,14 +42,13 @@ start si file key =
 perform :: RawFilePath -> Key -> CommandPerform
 perform file key = do
 	liftIO $ removeFile (fromRawFilePath file)
-	inRepo $ Git.Command.run
-		[ Param "rm"
-		, Param "--cached"
+	Annex.Queue.addCommand [] "rm"
+		[ Param "--cached"
 		, Param "--force"
 		, Param "--quiet"
 		, Param "--"
-		, File (fromRawFilePath file)
 		]
+		[fromRawFilePath file]
 	next $ cleanup file key
 
 cleanup :: RawFilePath -> Key -> CommandCleanup
diff --git a/doc/todo/optimization_needed__58___slow_uninit.mdwn b/doc/todo/optimization_needed__58___slow_uninit.mdwn
index 0b7e2d8e3..aeae0cbf1 100644
--- a/doc/todo/optimization_needed__58___slow_uninit.mdwn
+++ b/doc/todo/optimization_needed__58___slow_uninit.mdwn
@@ -20,3 +20,5 @@ git annex 8.20210127-g42239bc
 
 [[!meta author=yoh]]
 [[!tag projects/datalad]]
+
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/todo/optimization_needed__58___slow_uninit/comment_1_3d01d125ffea8dd247e68f716a9c636a._comment b/doc/todo/optimization_needed__58___slow_uninit/comment_1_3d01d125ffea8dd247e68f716a9c636a._comment
new file mode 100644
index 000000000..3c81325ad
--- /dev/null
+++ b/doc/todo/optimization_needed__58___slow_uninit/comment_1_3d01d125ffea8dd247e68f716a9c636a._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 1"""
+ date="2021-02-22T16:45:46Z"
+ content="""
+Also unannex is slow the same way. Looks like it can easily be fixed using
+git command queueing; I see no reason the rm needs to happen before
+changes to the working tree, as --cached makes the rm only operate on the
+index.
+
+Rest seem fast enough.
+"""]]

comment
diff --git a/doc/bugs/no_way_to_disable_repository_auto_upgrade/comment_4_7ea295a6c113ea0cc3e4e5ae28769190._comment b/doc/bugs/no_way_to_disable_repository_auto_upgrade/comment_4_7ea295a6c113ea0cc3e4e5ae28769190._comment
new file mode 100644
index 000000000..7945b1f8b
--- /dev/null
+++ b/doc/bugs/no_way_to_disable_repository_auto_upgrade/comment_4_7ea295a6c113ea0cc3e4e5ae28769190._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 4"""
+ date="2021-02-22T16:35:40Z"
+ content="""
+Yeah, that command you say you ran makes no sense.
+
+Now, running that command *does* upgrade the repo, if
+upgrading has not already been disabled in the git config.
+Because git-annex auto-upgrades on the first command run,
+and the fact that the command just errors out due to being
+used incorrectly doesn't prevent that from happening.
+
+But I get the feeling that command is not what you actually did?
+
+You can run `git config --global annex.autoupgraderepository false`
+and you only have to set it that one time for that machine and it will
+avoid all upgrades.
+"""]]

comment
diff --git a/doc/forum/Rename_local_repository_for_git-annex-info/comment_4_695a821eee66f8c4d4e22518edd15c40._comment b/doc/forum/Rename_local_repository_for_git-annex-info/comment_4_695a821eee66f8c4d4e22518edd15c40._comment
new file mode 100644
index 000000000..f744fc196
--- /dev/null
+++ b/doc/forum/Rename_local_repository_for_git-annex-info/comment_4_695a821eee66f8c4d4e22518edd15c40._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 4"""
+ date="2021-02-22T16:30:37Z"
+ content="""
+Yes, "here" is hardcoded. It could be made configurable in the git config,
+if there's actually a good reason to want to.
+"""]]
diff --git a/doc/git-annex-import/comment_3_3891ccc35010e1e5c328a9aa6b9e596b._comment b/doc/git-annex-import/comment_3_3891ccc35010e1e5c328a9aa6b9e596b._comment
new file mode 100644
index 000000000..27d00aad5
--- /dev/null
+++ b/doc/git-annex-import/comment_3_3891ccc35010e1e5c328a9aa6b9e596b._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""re: import from special directory remote fails due to running out of memory"""
+ date="2021-02-22T16:13:32Z"
+ content="""
+Importing from special remotes necessarily needs to hold the list of files
+in memory, or at least it seems like it would be hard to get it to stream
+over them. So there may be some way to decrease the memory use per file
+(currently 4.2 kb per file according to your numbers), possibly by around
+50%, but it would still scale with the number of files. The whole import
+interface would need to change to use trees to avoid that.
+It would be ok to file a bug report about this.
+
+The legacy directory import interface avoids such problems.
+"""]]

Added a comment: One possible workaround
diff --git a/doc/bugs/indeterminite_preferred_content_state_for_duplicated_file/comment_2_085f54265ce94186fe715df297785496._comment b/doc/bugs/indeterminite_preferred_content_state_for_duplicated_file/comment_2_085f54265ce94186fe715df297785496._comment
new file mode 100644
index 000000000..a60e22979
--- /dev/null
+++ b/doc/bugs/indeterminite_preferred_content_state_for_duplicated_file/comment_2_085f54265ce94186fe715df297785496._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="EvanDeaubl"
+ avatar="http://cdn.libravatar.org/avatar/00804f84646da416472678b573fd9d30"
+ subject="One possible workaround"
+ date="2021-02-22T16:23:40Z"
+ content="""
+I ran into this exact situation trying to split content across multiple repos by directory, and ran into a couple of files with many duplicate keys throughout the repo. I worked around it by applying a tag to the offending key, and including that tag as part of the preferred content expression:
+
+```
+git annex metadata -t common-signature $FILE_WITH_DUP_KEY
+git annex wanted . 'include=\"foo/*\" or include \"bar/*\" or metadata=tag=common-signature'
+```
+
+This would result in a file possibly being included in a repo where it wouldn't be otherwise (if it wasn't in one of the include directories to begin with), but in my case, the common files were few and small (2, both less than 100K).
+"""]]

Added a comment
diff --git a/doc/bugs/no_way_to_disable_repository_auto_upgrade/comment_3_f3c10f35956dff886d961f1351af71ef._comment b/doc/bugs/no_way_to_disable_repository_auto_upgrade/comment_3_f3c10f35956dff886d961f1351af71ef._comment
new file mode 100644
index 000000000..45e0ee3de
--- /dev/null
+++ b/doc/bugs/no_way_to_disable_repository_auto_upgrade/comment_3_f3c10f35956dff886d961f1351af71ef._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="zsolt1"
+ avatar="http://cdn.libravatar.org/avatar/ef26f34d5d953cf139c58e5dc4b5fe73"
+ subject="comment 3"
+ date="2021-02-21T18:11:33Z"
+ content="""
+@Lukey , thanks for pointing it out! Layer 8.
+"""]]

Added a comment
diff --git a/doc/todo/assistant_web_switch_repo_Internal_Server_Error/comment_1_b4add1998a9a81fb2c95539408bbeb64._comment b/doc/todo/assistant_web_switch_repo_Internal_Server_Error/comment_1_b4add1998a9a81fb2c95539408bbeb64._comment
new file mode 100644
index 000000000..3ba82122a
--- /dev/null
+++ b/doc/todo/assistant_web_switch_repo_Internal_Server_Error/comment_1_b4add1998a9a81fb2c95539408bbeb64._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="git-annex.branchable.com@d12f3f46c9222459d17f96bc7be04f7cd03a6732"
+ nickname="git-annex.branchable.com"
+ avatar="http://cdn.libravatar.org/avatar/e3748ecfbbcafc96ccec69fb2db01c3f"
+ subject="comment 1"
+ date="2021-02-21T15:50:47Z"
+ content="""
+Apologies, I realise I think I filed this as a \"todo\" instead of under \"bugs\", apologies. I can't see how to move it unfortunately...
+"""]]

Added a comment
diff --git a/doc/bugs/no_way_to_disable_repository_auto_upgrade/comment_2_dc24c6c0c60bb11d6d871fa62585276d._comment b/doc/bugs/no_way_to_disable_repository_auto_upgrade/comment_2_dc24c6c0c60bb11d6d871fa62585276d._comment
new file mode 100644
index 000000000..221c1c84d
--- /dev/null
+++ b/doc/bugs/no_way_to_disable_repository_auto_upgrade/comment_2_dc24c6c0c60bb11d6d871fa62585276d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="Lukey"
+ avatar="http://cdn.libravatar.org/avatar/c7c08e2efd29c692cc017c4a4ca3406b"
+ subject="comment 2"
+ date="2021-02-20T21:35:05Z"
+ content="""
+You're supposed to use `git config annex.autoupgraderepository false`.
+"""]]

Added a comment: reproduce
diff --git a/doc/bugs/no_way_to_disable_repository_auto_upgrade/comment_1_aab2cb260b68c25facd652946ea2aff7._comment b/doc/bugs/no_way_to_disable_repository_auto_upgrade/comment_1_aab2cb260b68c25facd652946ea2aff7._comment
new file mode 100644
index 000000000..fe7ef6317
--- /dev/null
+++ b/doc/bugs/no_way_to_disable_repository_auto_upgrade/comment_1_aab2cb260b68c25facd652946ea2aff7._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="zsolt1"
+ avatar="http://cdn.libravatar.org/avatar/ef26f34d5d953cf139c58e5dc4b5fe73"
+ subject="reproduce"
+ date="2021-02-20T19:06:44Z"
+ content="""
+disabling auto-upgrade was successful by 4 repos before I experienced this problem by the 5th one 
+"""]]

Add workaround
diff --git a/doc/todo/assistant_web_switch_repo_Internal_Server_Error.mdwn b/doc/todo/assistant_web_switch_repo_Internal_Server_Error.mdwn
index 62665d9a1..722866c4f 100644
--- a/doc/todo/assistant_web_switch_repo_Internal_Server_Error.mdwn
+++ b/doc/todo/assistant_web_switch_repo_Internal_Server_Error.mdwn
@@ -46,6 +46,10 @@ local repository version: 8
 
 This is macOS 11.2.1 (Big Sur), installed via `brew install git-annex`. I've tried the same behaviour on 2 separate macs, same error both times. It seems like the switching in the web UI is a bit tricky. I've also tried a few browsers (Safari, Chrome) and my dev browser without any ad blocking. It seems like there's an HTTP request to `/config/repository/switchto/...` which returns a 500.
 
+## Workaround
+
+It seems that if I stop the webapp, and start it again, it has actually switched repos. So it's a bit inconvenient, but usable nonetheless.
+
 ## Thanks
 
 I've just started the missing of moving from nextcloud to git-annex after the second random deletion of data by nextcloud. I'm deeply grateful to the authors for giving me the confidence of git to manage my files. Wonderful.

Initial report
diff --git a/doc/todo/assistant_web_switch_repo_Internal_Server_Error.mdwn b/doc/todo/assistant_web_switch_repo_Internal_Server_Error.mdwn
new file mode 100644
index 000000000..62665d9a1
--- /dev/null
+++ b/doc/todo/assistant_web_switch_repo_Internal_Server_Error.mdwn
@@ -0,0 +1,51 @@
+## Steps to reproduce:
+
+- create 2 separate repos
+- Top right: Repository: path dropdown
+  - Select the other repository
+
+## Expected result
+
+I expect the UI to switch over to the other repo.
+
+## Actual result
+
+```
+Internal Server Error
+HttpExceptionRequest Request {
+  host                 = "127.0.0.1"
+  port                 = 52482
+  secure               = False
+  requestHeaders       = [("Accept-Encoding","")]
+  path                 = "/"
+  queryString          = "?auth=REDACTED"
+  method               = "HEAD"
+  proxy                = Nothing
+  rawBody              = False
+  redirectCount        = 10
+  responseTimeout      = ResponseTimeoutDefault
+  requestVersion       = HTTP/1.1
+  proxySecureMode      = ProxySecureWithConnect
+}
+ (ConnectionFailure Network.Socket.connect: <socket: 51>: does not exist (Connection refused))
+```
+
+## Context
+
+```
+git-annex version: 8.20210127
+build flags: Assistant Webapp Pairing FsEvents TorrentParser MagicMime Feeds Testsuite S3 WebDAV
+dependency versions: aws-0.22 bloomfilter-2.0.1.0 cryptonite-0.28 DAV-1.3.4 feed-1.3.0.1 ghc-8.10.3 http-client-0.7.4 persistent-sqlite-2.11.0.0 torrent-10000.1.1 uuid-1.3.13 yesod-1.6.1.0
+key/value backends: SHA256E SHA256 SHA512E SHA512 SHA224E SHA224 SHA384E SHA384 SHA3_256E SHA3_256 SHA3_512E SHA3_512 SHA3_224E SHA3_224 SHA3_384E SHA3_384 SKEIN256E SKEIN256 SKEIN512E SKEIN512 BLAKE2B256E BLAKE2B256 BLAKE2B512E BLAKE2B512 BLAKE2B160E BLAKE2B160 BLAKE2B224E BLAKE2B224 BLAKE2B384E BLAKE2B384 BLAKE2BP512E BLAKE2BP512 BLAKE2S256E BLAKE2S256 BLAKE2S160E BLAKE2S160 BLAKE2S224E BLAKE2S224 BLAKE2SP256E BLAKE2SP256 BLAKE2SP224E BLAKE2SP224 SHA1E SHA1 MD5E MD5 WORM URL X*
+remote types: git gcrypt p2p S3 bup directory rsync web bittorrent webdav adb tahoe glacier ddar git-lfs httpalso borg hook external
+operating system: darwin x86_64
+supported repository versions: 8
+upgrade supported from repository versions: 0 1 2 3 4 5 6 7
+local repository version: 8
+```
+
+This is macOS 11.2.1 (Big Sur), installed via `brew install git-annex`. I've tried the same behaviour on 2 separate macs, same error both times. It seems like the switching in the web UI is a bit tricky. I've also tried a few browsers (Safari, Chrome) and my dev browser without any ad blocking. It seems like there's an HTTP request to `/config/repository/switchto/...` which returns a 500.
+
+## Thanks
+
+I've just started the missing of moving from nextcloud to git-annex after the second random deletion of data by nextcloud. I'm deeply grateful to the authors for giving me the confidence of git to manage my files. Wonderful.

diff --git a/doc/bugs/no_way_to_disable_repository_auto_upgrade.mdwn b/doc/bugs/no_way_to_disable_repository_auto_upgrade.mdwn
new file mode 100644
index 000000000..e0423654b
--- /dev/null
+++ b/doc/bugs/no_way_to_disable_repository_auto_upgrade.mdwn
@@ -0,0 +1,48 @@
+### Please describe the problem.
+
+git-annex upgrades the repository before I could set the annex.autoupgraderepository to false
+
+### What steps will reproduce the problem?
+
+Its not trivial to reproduce. After an auto upgrade at one repo from v5 to v8 crashed, I decided to freeze all my v5 repositories first. By requiring the repo version and then immediately setting autoupgrade to false I realized the repo was upgraded during the command `git annex config --set autoupgraderepository false`
+
+### What version of git-annex are you using? On what operating system?
+
+git-annex version: 8.20200226
+ubuntu 20.04
+
+### Please provide any additional information below.
+
+[[!format sh """
+$ git annex version
+git-annex version: 8.20200226
+build flags: Assistant Webapp Pairing S3 WebDAV Inotify DBus DesktopNotify TorrentParser MagicMime Feeds Testsuite
+dependency versions: aws-0.20 bloomfilter-2.0.1.0 cryptonite-0.25 DAV-1.3.3 feed-1.0.1.0 ghc-8.6.5 http-client-0.5.14 persistent-sqlite-2.9.3 torrent-10000.1.1 uuid-1.3.13 yesod-1.6.0
+key/value backends: SHA256E SHA256 SHA512E SHA512 SHA224E SHA224 SHA384E SHA384 SHA3_256E SHA3_256 SHA3_512E SHA3_512 SHA3_224E SHA3_224 SHA3_384E SHA3_384 SKEIN256E SKEIN256 SKEIN512E SKEIN512 BLAKE2B256E BLAKE2B256 BLAKE2B512E BLAKE2B512 BLAKE2B160E BLAKE2B160 BLAKE2B224E BLAKE2B224 BLAKE2B384E BLAKE2B384 BLAKE2BP512E BLAKE2BP512 BLAKE2S256E BLAKE2S256 BLAKE2S160E BLAKE2S160 BLAKE2S224E BLAKE2S224 BLAKE2SP256E BLAKE2SP256 BLAKE2SP224E BLAKE2SP224 SHA1E SHA1 MD5E MD5 WORM URL
+remote types: git gcrypt p2p S3 bup directory rsync web bittorrent webdav adb tahoe glacier ddar git-lfs hook external
+operating system: linux x86_64
+supported repository versions: 8
+upgrade supported from repository versions: 0 1 2 3 4 5 6 7
+local repository version: 5
+$ git annex config --set autoupgraderepository false
+autoupgraderepository false ok
+(recording state in git...)
+$ git annex version
+git-annex version: 8.20200226
+build flags: Assistant Webapp Pairing S3 WebDAV Inotify DBus DesktopNotify TorrentParser MagicMime Feeds Testsuite
+dependency versions: aws-0.20 bloomfilter-2.0.1.0 cryptonite-0.25 DAV-1.3.3 feed-1.0.1.0 ghc-8.6.5 http-client-0.5.14 persistent-sqlite-2.9.3 torrent-10000.1.1 uuid-1.3.13 yesod-1.6.0
+key/value backends: SHA256E SHA256 SHA512E SHA512 SHA224E SHA224 SHA384E SHA384 SHA3_256E SHA3_256 SHA3_512E SHA3_512 SHA3_224E SHA3_224 SHA3_384E SHA3_384 SKEIN256E SKEIN256 SKEIN512E SKEIN512 BLAKE2B256E BLAKE2B256 BLAKE2B512E BLAKE2B512 BLAKE2B160E BLAKE2B160 BLAKE2B224E BLAKE2B224 BLAKE2B384E BLAKE2B384 BLAKE2BP512E BLAKE2BP512 BLAKE2S256E BLAKE2S256 BLAKE2S160E BLAKE2S160 BLAKE2S224E BLAKE2S224 BLAKE2SP256E BLAKE2SP256 BLAKE2SP224E BLAKE2SP224 SHA1E SHA1 MD5E MD5 WORM URL
+remote types: git gcrypt p2p S3 bup directory rsync web bittorrent webdav adb tahoe glacier ddar git-lfs hook external
+operating system: linux x86_64
+supported repository versions: 8
+upgrade supported from repository versions: 0 1 2 3 4 5 6 7
+local repository version: 8
+
+# End of transcript or log.
+"""]]
+
+### Have you had any luck using git-annex before? (Sometimes we get tired of reading bug reports all day and a lil' positive end note does wonders)
+
+I am using it since v5 and only v5 for repos like more 100k filecount and size ~800GB. Worked perfectly on Linux desktop, android, phone, tab, raspberry. The greatest sync tool I ever had. I am a little bit worried about the upgrade to v8 from v5 now :) 
+
+

Added a comment
diff --git a/doc/forum/Help_with_get/comment_5_92e48d21fd83c0f7e69a5bb7b4c4f4ee._comment b/doc/forum/Help_with_get/comment_5_92e48d21fd83c0f7e69a5bb7b4c4f4ee._comment
new file mode 100644
index 000000000..9acbbbd53
--- /dev/null
+++ b/doc/forum/Help_with_get/comment_5_92e48d21fd83c0f7e69a5bb7b4c4f4ee._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="jwrauch"
+ avatar="http://cdn.libravatar.org/avatar/0e83010187ef0c8c587e0c99e2ca5474"
+ subject="comment 5"
+ date="2021-02-19T18:58:14Z"
+ content="""
+Okay, so it seems like it was my usb port.  I tried plugging the drive into a different port and the whole repository copied over.  I'd love to know more if anyone has more information about what was happening, but I think the issue is resolved for now.  
+"""]]

initial observation about slow uninit
diff --git a/doc/todo/optimization_needed__58___slow_uninit.mdwn b/doc/todo/optimization_needed__58___slow_uninit.mdwn
new file mode 100644
index 000000000..0b7e2d8e3
--- /dev/null
+++ b/doc/todo/optimization_needed__58___slow_uninit.mdwn
@@ -0,0 +1,22 @@
+I am running `git annex uninit` on  a quite heavy in number of annexed (text) files repository (can share a tarball if needed -- the product of https://github.com/con/tinuous/ to please those hating CI log navigation UIs ;-) ).
+
+the box on which it runs is very IO busy ATM, but the fact that I saw no progress from `uninit` for almost 10 minutes made me look into:
+
+```
+$> px | grep -A7 git-anne[x]
+yoh      30339  0.2  0.0 1074123060 38060 pts/4 Sl+ 11:49   0:01  |       \_ /home/yoh/miniconda3/envs/tinuous/bin/git-annex uninit
+yoh      30396  0.0  0.0  13892  5492 pts/4    S+   11:49   0:00  |           \_ git --git-dir=.git --work-tree=. --literal-pathspecs ls-files --stage -z --
+yoh      30398  0.0  0.0  14720  2988 pts/4    S+   11:49   0:00  |           \_ git --git-dir=.git --work-tree=. --literal-pathspecs cat-file --batch-check=%(objectname) %(objecttype) %(objectsize) --buffer
+yoh      30399  0.0  0.0  14848  4108 pts/4    S+   11:49   0:00  |           \_ git --git-dir=.git --work-tree=. --literal-pathspecs cat-file --batch=%(objectname) %(objecttype) %(objectsize) --buffer
+yoh      30417  0.0  0.0      0     0 pts/4    Z+   11:49   0:00  |           \_ [git] <defunct>
+yoh      30421  0.0  0.0      0     0 pts/4    Z+   11:49   0:00  |           \_ [git] <defunct>
+yoh      27761  0.0  0.0 112028  6892 pts/4    D+   11:51   0:00  |           \_ git --git-dir=.git --work-tree=. --literal-pathspecs rm --cached --force --quiet -- 01/21/github/pr/UNK/5f6fe634a863281742c0eb7d238c111da6e2e52e/Test on macOS/758/test (brew)/5_Set up Python 3.6.txt
+
+```
+
+so `git annex` invokes separate `git rm` on each file.  Having thousands of those is doomed to make it slow.  Unfortunately I have not spotted a `--batch` mode in `git rm --help` but I wondered if may be at least multiple files could be requested to be removed in a single call instead of running that rm per each file?
+
+git annex 8.20210127-g42239bc
+
+[[!meta author=yoh]]
+[[!tag projects/datalad]]

Added a comment
diff --git a/doc/forum/Help_with_get/comment_4_863d03a8e52335d8a210320d8a02c553._comment b/doc/forum/Help_with_get/comment_4_863d03a8e52335d8a210320d8a02c553._comment
new file mode 100644
index 000000000..1183ecc7c
--- /dev/null
+++ b/doc/forum/Help_with_get/comment_4_863d03a8e52335d8a210320d8a02c553._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="jwrauch"
+ avatar="http://cdn.libravatar.org/avatar/0e83010187ef0c8c587e0c99e2ca5474"
+ subject="comment 4"
+ date="2021-02-19T16:19:52Z"
+ content="""
+Sorry, formatting:
+
+    $ git annex get . --debug
+    ok
+    get recorder/2020-philippines/20200906_165152.mp4 (from avi...)
+    [2021-02-19 11:11:22.1489056] call: cp [\"--reflink=auto\",\"--preserve=timestamps\",\"E:\\video\\.git\\annex\\objects\\d88\\080\\SHA256E-s493726419--95dd6a377dce064935ab2e8c0dda2f3c4d9d2b33e0efaca34fceda200cbee249.mp4\\SHA256E-       s493726419--95dd6a377dce064935ab2e8c0dda2f3c4d9d2b33e0efaca34fceda200cbee249.mp4\",\".git\\annex\\tmp\\SHA256E-s493726419--95dd6a377dce064935ab2e8c0dda2f3c4d9d2b33e0efaca34fceda200cbee249.mp4\"]
+    10%   46.12 MiB        87 MiB/s 4scp: error writing '.git\annex\tmp\SHA256E-s493726419--95dd6a377dce064935ab2e8c0dda2f3c4d9d2b33e0efaca34fceda200cbee249.mp4': Permission denied
+
+"""]]

Added a comment
diff --git a/doc/forum/Help_with_get/comment_3_f523e44daca53b3d99350e0d3f7a8874._comment b/doc/forum/Help_with_get/comment_3_f523e44daca53b3d99350e0d3f7a8874._comment
new file mode 100644
index 000000000..ea7c51984
--- /dev/null
+++ b/doc/forum/Help_with_get/comment_3_f523e44daca53b3d99350e0d3f7a8874._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="jwrauch"
+ avatar="http://cdn.libravatar.org/avatar/0e83010187ef0c8c587e0c99e2ca5474"
+ subject="comment 3"
+ date="2021-02-19T16:17:33Z"
+ content="""
+I ran the get command with the debug flag and the output is pretty extensive.  It successfully transferred two files before it failed, so I'm posting from the 'ok' of the last success.  Here is the command and output:
+
+$ git annex get . --debug
+...
+ok
+get recorder/2020-philippines/20200906_165152.mp4 (from avi...)
+[2021-02-19 11:11:22.1489056] call: cp [\"--reflink=auto\",\"--preserve=timestamps\",\"E:\\video\\.git\\annex\\objects\\d88\\080\\SHA256E-s493726419--95dd6a377dce064935ab2e8c0dda2f3c4d9d2b33e0efaca34fceda200cbee249.mp4\\SHA256E-s493726419--95dd6a377dce064935ab2e8c0dda2f3c4d9d2b33e0efaca34fceda200cbee249.mp4\",\".git\\annex\\tmp\\SHA256E-s493726419--95dd6a377dce064935ab2e8c0dda2f3c4d9d2b33e0efaca34fceda200cbee249.mp4\"]
+10%   46.12 MiB        87 MiB/s 4scp: error writing '.git\annex\tmp\SHA256E-s493726419--95dd6a377dce064935ab2e8c0dda2f3c4d9d2b33e0efaca34fceda200cbee249.mp4': Permission denied
+
+"""]]

Added a comment
diff --git a/doc/forum/Help_with_get/comment_2_137f89ea9c381cdbf57da78308a46078._comment b/doc/forum/Help_with_get/comment_2_137f89ea9c381cdbf57da78308a46078._comment
new file mode 100644
index 000000000..13bf43f4b
--- /dev/null
+++ b/doc/forum/Help_with_get/comment_2_137f89ea9c381cdbf57da78308a46078._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="jwrauch"
+ avatar="http://cdn.libravatar.org/avatar/0e83010187ef0c8c587e0c99e2ca5474"
+ subject="comment 2"
+ date="2021-02-19T16:10:00Z"
+ content="""
+I'm using git annex version: 8.20200815-g335aae266.  And I followed the instructions the link provided.  I looked into wls but decided to try this first.  Is that a better approach?
+"""]]

Added a comment
diff --git a/doc/forum/Help_with_get/comment_1_439c7562d94a969fd841cc44628abedd._comment b/doc/forum/Help_with_get/comment_1_439c7562d94a969fd841cc44628abedd._comment
new file mode 100644
index 000000000..8ac255198
--- /dev/null
+++ b/doc/forum/Help_with_get/comment_1_439c7562d94a969fd841cc44628abedd._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="Lukey"
+ avatar="http://cdn.libravatar.org/avatar/c7c08e2efd29c692cc017c4a4ca3406b"
+ subject="comment 1"
+ date="2021-02-19T15:43:46Z"
+ content="""
+Hi,
+What version of git-annex are you using (Output of `git annex version`)? And since you are on windows, did you follow the install instructions [[here|install/Windows/]] or are you using wsl or something else? Finally, can you run the failing command with `--debug` and post the output here?
+"""]]

diff --git a/doc/forum/Help_with_get.mdwn b/doc/forum/Help_with_get.mdwn
new file mode 100644
index 000000000..997a5baf3
--- /dev/null
+++ b/doc/forum/Help_with_get.mdwn
@@ -0,0 +1 @@
+I'm new to git annex, but I couldn't find any other posts describing this error.  I just set up repositories on two external 1TB, NTFS formatted hard drives and I'm working on a windows 10 os.  I followed the walkthrough, setting the repository up on one drive, then cloning it on the other, and now I'm syncing the content (I first sync then get, but the problem occurs when I use the --content flag on sync as well).  After a few files are successfully transferred, the process stalls part way through a file saying an "scp error writing 'file': Permission denied"???  Git annex and git processes don't end and I need to forcefully close the terminal and unplug and replug the drive back in before I can resume.  I don't know if it is something with using git annex on Windows(I was automatically put on an adjusted branch, which I don't fully understand), or the NTFS drives, or maybe the hard drive is failing.  Any advice people can give would be appreciated as this issue is persistent enough (every ~3 files) that it is making git annex unusable.  

Added a comment
diff --git a/doc/forum/Rename_local_repository_for_git-annex-info/comment_3_c75652b23bc4554d43593d1984c9c5d9._comment b/doc/forum/Rename_local_repository_for_git-annex-info/comment_3_c75652b23bc4554d43593d1984c9c5d9._comment
new file mode 100644
index 000000000..3d268b811
--- /dev/null
+++ b/doc/forum/Rename_local_repository_for_git-annex-info/comment_3_c75652b23bc4554d43593d1984c9c5d9._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="Lukey"
+ avatar="http://cdn.libravatar.org/avatar/c7c08e2efd29c692cc017c4a4ca3406b"
+ subject="comment 3"
+ date="2021-02-19T07:28:12Z"
+ content="""
+AFAIK, the `[here]` can't be changed, it just means \"it is this local repository\". Now, if you add another repository as a git remote, then it'll show `<description>[<name of git remote>]` for the git remote.
+"""]]

Added a comment
diff --git a/doc/git-annex-import/comment_2_e62b59d5c9cee04a77c51799624a3357._comment b/doc/git-annex-import/comment_2_e62b59d5c9cee04a77c51799624a3357._comment
new file mode 100644
index 000000000..7eade4625
--- /dev/null
+++ b/doc/git-annex-import/comment_2_e62b59d5c9cee04a77c51799624a3357._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="Lukey"
+ avatar="http://cdn.libravatar.org/avatar/c7c08e2efd29c692cc017c4a4ca3406b"
+ subject="comment 2"
+ date="2021-02-19T07:16:25Z"
+ content="""
+Yes, just `cp` or `mv` the files inside the repo and `git annex add` them as usual.
+"""]]

Added a comment: how to rename/remove the [here] ??
diff --git a/doc/forum/Rename_local_repository_for_git-annex-info/comment_2_a13ef241d6d24b4abee3eedff18032a8._comment b/doc/forum/Rename_local_repository_for_git-annex-info/comment_2_a13ef241d6d24b4abee3eedff18032a8._comment
new file mode 100644
index 000000000..6080a6fdb
--- /dev/null
+++ b/doc/forum/Rename_local_repository_for_git-annex-info/comment_2_a13ef241d6d24b4abee3eedff18032a8._comment
@@ -0,0 +1,21 @@
+[[!comment format=mdwn
+ username="jodumont"
+ avatar="http://cdn.libravatar.org/avatar/343b334cbc4b2bff019ab6b525a2c9ed"
+ subject="how to rename/remove the [here] ??"
+ date="2021-02-19T04:56:46Z"
+ content="""
+I'm able to change the description of my repo but not the name, which is by default and in that case **[here]**
+
+> user@machine:/srv/data$ git-annex info  
+trusted repositories: 0  
+semitrusted repositories: 3  
+00000000-0000-0000-0000-000000000001 -- web  
+00000000-0000-0000-0000-000000000002 -- bittorrent  
+xxxxxxxx-xxx-xxxx-xxxx-xxxxxxxxxxxx -- sub.domain.tld:/srv/data **[here]**  
+untrusted repositories: xxx  
+transfers in progress: xxxx  
+available local disk space: 2.03 petabytes (+1 gigabyte reserved)  
+
+## How I could edit the name and/or name it properly when I init it ?
+
+"""]]

Added a comment: Explanation for a noGUI usage
diff --git a/doc/forum/Starting_assistant_from_CLI/comment_5_8d657646080bf2b99b7792993b877502._comment b/doc/forum/Starting_assistant_from_CLI/comment_5_8d657646080bf2b99b7792993b877502._comment
new file mode 100644
index 000000000..f327bab3b
--- /dev/null
+++ b/doc/forum/Starting_assistant_from_CLI/comment_5_8d657646080bf2b99b7792993b877502._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="jodumont"
+ avatar="http://cdn.libravatar.org/avatar/343b334cbc4b2bff019ab6b525a2c9ed"
+ subject="Explanation for a noGUI usage"
+ date="2021-02-19T04:39:34Z"
+ content="""
+I had that issue, git-annex is installed on a noGUI remote machine so the directory and the file **~/.config/git-annex/autostart** didn't exist.
+I think it worth to mention than you could create by hand **~/.config/git-annex/autostart**
+
+> mkdir ~/.config/git-annex/; touch ~/.config/git-annex/autostart
+
+and in simply add the path of your git-annex you want to start such as **/srv/data** for this example (*which contain a .git/annex/ directory*) then you are ready to go
+
+> cd /srv/data; git annex assistant --autostart
+"""]]

Added a comment: import from special directory remote fails due to running out of memory
diff --git a/doc/git-annex-import/comment_1_8961635a772b4ddb5ba1e04a50034e6a._comment b/doc/git-annex-import/comment_1_8961635a772b4ddb5ba1e04a50034e6a._comment
new file mode 100644
index 000000000..4dbdc45cd
--- /dev/null
+++ b/doc/git-annex-import/comment_1_8961635a772b4ddb5ba1e04a50034e6a._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="georg.schnabel@bd6be2144f897f5caa0028e0dd1e0a65634add81"
+ nickname="georg.schnabel"
+ avatar="http://cdn.libravatar.org/avatar/b58e4e0101a95b57d55da575ca21f510"
+ subject="import from special directory remote fails due to running out of memory "
+ date="2021-02-17T14:29:49Z"
+ content="""
+First of all, git annex is an awesome tool, I like it very much!
+
+When trying to `git annex import` from a special directory remote with a large number of files (~4 millions) with a cumulative size of about 1TB, git annex takes up all main memory during the final update remote/ref step on a machine with 16G of main memory and is then killed by the system. This also happens when supplying the `--no-content` option. Is there a way to make git annex less memory demanding when importing from a special directory remote with a large number of files?
+"""]]

diff --git a/doc/git-annex-import.mdwn b/doc/git-annex-import.mdwn
index afe37a769..f36bf0be5 100644
--- a/doc/git-annex-import.mdwn
+++ b/doc/git-annex-import.mdwn
@@ -105,15 +105,17 @@ the tree of files on the remote, even when importing into a subdirectory.
 
 # IMPORTING FROM A DIRECTORY
 
-When run with a path, `git annex import` moves files from somewhere outside
-the git working copy, and adds them to the annex.
+When run with a path, `git annex import` **moves** files from somewhere outside
+the git working copy, and adds them to the annex. In contrast to importing 
+from a special directory remote, imported files are **deleted from the given path**.
 
 This is a legacy interface. It is still supported, but please consider
 switching to importing from a directory special remote instead, using the
 interface documented above.
 
 Individual files to import can be specified. If a directory is specified,
-the entire directory is imported.
+the entire directory is imported. Please note that the following instruction
+will **delete all files from the source directory**.   
   
         	git annex import /media/camera/DCIM/*
 

windows build fix from jwodder
diff --git a/Remote/Git.hs b/Remote/Git.hs
index 3ca65c4f6..596c259c5 100644
--- a/Remote/Git.hs
+++ b/Remote/Git.hs
@@ -46,6 +46,7 @@ import Logs.Location
 import Utility.Metered
 import Utility.CopyFile
 import Utility.Env
+import Utility.FileMode
 import Utility.Batch
 import Utility.SimpleProtocol
 import Utility.Touch
@@ -70,7 +71,6 @@ import Messages.Progress
 
 #ifndef mingw32_HOST_OS
 import qualified Utility.RawFilePath as R
-import Utility.FileMode
 #endif
 
 import Control.Concurrent
@@ -654,7 +654,7 @@ copyFromRemoteCheap st repo
 			)
 	| otherwise = Nothing
 #else
-copyFromRemoteCheap _ _ _ = Nothing
+copyFromRemoteCheap _ _ = Nothing
 #endif
 
 {- Tries to copy a key's content to a remote's annex. -}
@@ -927,6 +927,7 @@ newCopyCoWTried = CopyCoWTried <$> newEmptyMVar
 fileCopier :: State -> Copier
 #ifdef mingw32_HOST_OS
 fileCopier _st src dest k meterupdate check verifyconfig = docopy
+  where
 #else
 fileCopier st src dest k meterupdate check verifyconfig =
 	-- If multiple threads reach this at the same time, they
diff --git a/doc/bugs/Windows_build_failing_as_of_commit_cb7bb3e.mdwn b/doc/bugs/Windows_build_failing_as_of_commit_cb7bb3e.mdwn
index 2ae07ac47..3352bb865 100644
--- a/doc/bugs/Windows_build_failing_as_of_commit_cb7bb3e.mdwn
+++ b/doc/bugs/Windows_build_failing_as_of_commit_cb7bb3e.mdwn
@@ -2,3 +2,5 @@ As of commit cb7bb3e, trying to build git-annex on Windows fails with a syntax e
 
 [[!meta author=jwodder]]
 [[!tag projects/datalad]]
+
+> applied, thanks [[done]] --[[Joey]]

comment
diff --git a/doc/forum/Reverse_index_key_to_list_of_file_paths/comment_5_022728be6cd3ac168a74d16baf29c0e1._comment b/doc/forum/Reverse_index_key_to_list_of_file_paths/comment_5_022728be6cd3ac168a74d16baf29c0e1._comment
new file mode 100644
index 000000000..5895b8bc7
--- /dev/null
+++ b/doc/forum/Reverse_index_key_to_list_of_file_paths/comment_5_022728be6cd3ac168a74d16baf29c0e1._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 5"""
+ date="2021-02-15T17:25:05Z"
+ content="""
+git grep doesn't use an index per se, but is probably faster
+than `find` at least sometimes. And probably somewhat faster than things
+involving `git-annex find` too.
+
+It's unfortunate that `git grep` doesn't search on the content of symlink
+texts, so that can't be used to find locked files.
+
+The equivilant using git-annex find, which will find both types:
+
+	git annex find --format '${key}\n' | grep SHA256E-s320029--488e29f5584ba4e474db95aa42fbb58ddb92f2a59bc0b24a91171acb4d8f4828.png
+"""]]

Added a comment
diff --git a/doc/bugs/__91__Patch__93___fix___34__mdwn2man__58___cannot_execute_-_...__34__/comment_2_9f168f9859b90aa41a782085f020b54d._comment b/doc/bugs/__91__Patch__93___fix___34__mdwn2man__58___cannot_execute_-_...__34__/comment_2_9f168f9859b90aa41a782085f020b54d._comment
new file mode 100644
index 000000000..fe072778d
--- /dev/null
+++ b/doc/bugs/__91__Patch__93___fix___34__mdwn2man__58___cannot_execute_-_...__34__/comment_2_9f168f9859b90aa41a782085f020b54d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="falsifian"
+ avatar="http://cdn.libravatar.org/avatar/59c3c23c500d20d83ecb9d1f149be9ae"
+ subject="comment 2"
+ date="2021-02-12T03:52:37Z"
+ content="""
+Thanks for the tip. (FYI: I'm working on packaging it for OpenBSD. Currently we just have a hack in place that manually runs the mdwn2man script after the cabal build. The Cabal packaging module it's built on probably isn't designed to call a Makefile but there may be some way to do it. In any case, it seems to work, so we might just leave it as is.)
+"""]]

diff --git a/doc/bugs/Windows_build_failing_as_of_commit_cb7bb3e.mdwn b/doc/bugs/Windows_build_failing_as_of_commit_cb7bb3e.mdwn
index 29323babe..2ae07ac47 100644
--- a/doc/bugs/Windows_build_failing_as_of_commit_cb7bb3e.mdwn
+++ b/doc/bugs/Windows_build_failing_as_of_commit_cb7bb3e.mdwn
@@ -1 +1,4 @@
-As of commit cb7bb3e, trying to build git-annex on Windows fails with a syntax error, which (once fixed) is replaced by a type error and an undefined name error.  All of these can be fixed with this patch: https://raw.githubusercontent.com/datalad/git-annex/32c2244753ae217a081109e1694bc83fe7a2da21/patches/20210211-cb7bb3e4b-windows-fix.patch
+As of commit cb7bb3e, trying to build git-annex on Windows fails with a syntax error, which (once fixed) is replaced by a type error and an undefined name error.  All of these can be fixed with [this patch](https://raw.githubusercontent.com/datalad/git-annex/32c2244753ae217a081109e1694bc83fe7a2da21/patches/20210211-cb7bb3e4b-windows-fix.patch).
+
+[[!meta author=jwodder]]
+[[!tag projects/datalad]]

diff --git a/doc/bugs/Windows_build_failing_as_of_commit_cb7bb3e.mdwn b/doc/bugs/Windows_build_failing_as_of_commit_cb7bb3e.mdwn
new file mode 100644
index 000000000..29323babe
--- /dev/null
+++ b/doc/bugs/Windows_build_failing_as_of_commit_cb7bb3e.mdwn
@@ -0,0 +1 @@
+As of commit cb7bb3e, trying to build git-annex on Windows fails with a syntax error, which (once fixed) is replaced by a type error and an undefined name error.  All of these can be fixed with this patch: https://raw.githubusercontent.com/datalad/git-annex/32c2244753ae217a081109e1694bc83fe7a2da21/patches/20210211-cb7bb3e4b-windows-fix.patch

comment
diff --git a/doc/todo/OPT__58_____34__bundle__34___get_+_check___40__of_checksum__41___in_a_single_operation/comment_12_f85f81450c5d59e6722b46299f2ae29c._comment b/doc/todo/OPT__58_____34__bundle__34___get_+_check___40__of_checksum__41___in_a_single_operation/comment_12_f85f81450c5d59e6722b46299f2ae29c._comment
new file mode 100644
index 000000000..02eab47cd
--- /dev/null
+++ b/doc/todo/OPT__58_____34__bundle__34___get_+_check___40__of_checksum__41___in_a_single_operation/comment_12_f85f81450c5d59e6722b46299f2ae29c._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""re: comment 9"""
+ date="2021-02-11T01:33:47Z"
+ content="""
+Not a bad idea, yoh!
+
+It could be taken further: Keep reading from the file as it grows and hash
+incrementally. Use inotify to know when more has been written, or poll
+periodically or when PROGRESS is received. If the hash is wrong at the end,
+rehash the file. Only remotes that write chunks out of order would pay a
+time penalty for that extra hashing.
+
+That could be enabled by a protocol extension. Or disabled by a protocol
+extension for that matter, since remotes that write out of order are
+probably rare.
+"""]]
diff --git a/doc/todo/OPT__58_____34__bundle__34___get_+_check___40__of_checksum__41___in_a_single_operation/comment_9_4f4f4a42adafe52207ed32a5d20e94be._comment b/doc/todo/OPT__58_____34__bundle__34___get_+_check___40__of_checksum__41___in_a_single_operation/comment_9_4f4f4a42adafe52207ed32a5d20e94be._comment
index befeac793..41b1d41ac 100644
--- a/doc/todo/OPT__58_____34__bundle__34___get_+_check___40__of_checksum__41___in_a_single_operation/comment_9_4f4f4a42adafe52207ed32a5d20e94be._comment
+++ b/doc/todo/OPT__58_____34__bundle__34___get_+_check___40__of_checksum__41___in_a_single_operation/comment_9_4f4f4a42adafe52207ed32a5d20e94be._comment
@@ -1,6 +1,6 @@
 [[!comment format=mdwn
  username="joey"
- subject="""comment 9"""
+ subject="""update"""
  date="2021-02-10T16:42:46Z"
  content="""
 Incremental hashing implemented for transfers over ssh and tor.

incremental checksum for local remotes
This benchmarks only slightly faster than the old git-annex. Eg, for a 1
gb file, 14.56s vs 15.57s. (On a ram disk; there would certianly be
more of an effect if the file was written to disk and didn't stay in
cache.)
Commenting out the updateIncremental calls make the same run in 6.31s.
May be that overhead in the implementation, other than the actual
checksumming, is slowing it down. Eg, MVar access.
(I also tried using 10x larger chunks, which did not change the speed.)
diff --git a/CHANGELOG b/CHANGELOG
index 580d5832a..b54546442 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -24,8 +24,8 @@ git-annex (8.20210128) UNRELEASED; urgency=medium
   * Include libkqueue.h file needed to build the assistant on BSDs.
   * Tahoe: Avoid verifying hash after download, since tahoe does sufficient
     verification itself.
-  * Checksum as content is received from a remote git-annex repository
-    over ssh/p2p protocols, rather than doing it in a second pass.
+  * Checksum as content is received from a remote git-annex repository,
+    rather than doing it in a second pass.
   * Bugfix: fsck --from a ssh remote did not actually check that the
     content on the remote is not corrupted.
 
diff --git a/Remote/Git.hs b/Remote/Git.hs
index ec20a3cc8..3ca65c4f6 100644
--- a/Remote/Git.hs
+++ b/Remote/Git.hs
@@ -62,7 +62,10 @@ import Annex.Path
 import Creds
 import Types.NumCopies
 import Types.ProposedAccepted
+import Types.Backend
+import Backend
 import Annex.Action
+import Annex.Verify
 import Messages.Progress
 
 #ifndef mingw32_HOST_OS
@@ -542,11 +545,12 @@ copyFromRemote'' repo forcersync r st@(State connpool _ _ _ _) key file dest met
 		-- run copy from perspective of remote
 		onLocalFast st $ Annex.Content.prepSendAnnex key >>= \case
 			Just (object, checksuccess) -> do
+				let verify = Annex.Content.RemoteVerify r
 				copier <- mkCopier hardlink st
 				(ok, v) <- runTransfer (Transfer Download u (fromKey id key))
 					file Nothing stdRetry $ \p ->
 						metered (Just (combineMeterUpdate p meterupdate)) key $ \_ p' -> 
-							copier object dest key p' checksuccess
+							copier object dest key p' checksuccess verify
 				if ok
 					then return v
 					else giveup "failed to retrieve content from remote"
@@ -685,12 +689,12 @@ copyToRemote' repo r st@(State connpool duc _ _ _) key file meterupdate
 		res <- onLocalFast st $ ifM (Annex.Content.inAnnex key)
 			( return True
 			, runTransfer (Transfer Download u (fromKey id key)) file Nothing stdRetry $ \p -> do
-				copier <- mkCopier hardlink st
 				let verify = Annex.Content.RemoteVerify r
+				copier <- mkCopier hardlink st
 				let rsp = RetrievalAllKeysSecure
 				res <- logStatusAfter key $ Annex.Content.getViaTmp rsp verify key file $ \dest ->
 					metered (Just (combineMeterUpdate meterupdate p)) key $ \_ p' -> 
-						copier object (fromRawFilePath dest) key p' (liftIO checksuccessio)
+						copier object (fromRawFilePath dest) key p' (liftIO checksuccessio) verify
 				Annex.Content.saveState True
 				return res
 			)
@@ -825,7 +829,7 @@ wantHardLink = (annexHardLink <$> Annex.getGitConfig)
 -- from is implicitly trusted, so no expensive verification needs to be
 -- done. Also returns Verified if the key's content is verified while
 -- copying it.
-type Copier = FilePath -> FilePath -> Key -> MeterUpdate -> Annex Bool -> Annex (Bool, Verification)
+type Copier = FilePath -> FilePath -> Key -> MeterUpdate -> Annex Bool -> VerifyConfig -> Annex (Bool, Verification)
 
 mkCopier :: Bool -> State -> Annex Copier
 mkCopier remotewanthardlink st = do
@@ -833,13 +837,13 @@ mkCopier remotewanthardlink st = do
 	localwanthardlink <- wantHardLink
 	let linker = \src dest -> createLink src dest >> return True
 	if remotewanthardlink || localwanthardlink
-		then return $ \src dest k p check ->
+		then return $ \src dest k p check verifyconfig ->
 			ifM (liftIO (catchBoolIO (linker src dest)))
 				( ifM check
 					( return (True, Verified)
 					, return (False, UnVerified)
 					)
-				, copier src dest k p check
+				, copier src dest k p check verifyconfig
 				)
 		else return copier
 
@@ -922,9 +926,9 @@ newCopyCoWTried = CopyCoWTried <$> newEmptyMVar
  -}
 fileCopier :: State -> Copier
 #ifdef mingw32_HOST_OS
-fileCopier _st src dest k meterupdate check = docopy
+fileCopier _st src dest k meterupdate check verifyconfig = docopy
 #else
-fileCopier st src dest k meterupdate check =
+fileCopier st src dest k meterupdate check verifyconfig =
 	-- If multiple threads reach this at the same time, they
 	-- will both try CoW, which is acceptable.
 	ifM (liftIO $ isEmptyMVar copycowtried)
@@ -953,14 +957,16 @@ fileCopier st src dest k meterupdate check =
 	dest' = toRawFilePath dest
 
 	docopy = do
+		iv <- startVerifyKeyContentIncrementally verifyconfig k
+
 		-- The file might have had the write bit removed,
 		-- so make sure we can write to it.
 		void $ liftIO $ tryIO $ allowWrite dest'
 
 		liftIO $ withBinaryFile dest ReadWriteMode $ \hdest ->
 			withBinaryFile src ReadMode $ \hsrc -> do
-				sofar <- compareexisting hdest hsrc zeroBytesProcessed
-				docopy' hdest hsrc sofar
+				sofar <- compareexisting iv hdest hsrc zeroBytesProcessed
+				docopy' iv hdest hsrc sofar
 
 		-- Copy src mode and mtime.
 		mode <- liftIO $ fileMode <$> getFileStatus src
@@ -969,24 +975,30 @@ fileCopier st src dest k meterupdate check =
 		liftIO $ touch dest' mtime False
 
 		ifM check
-			( return (True, UnVerified)
+			( case iv of
+				Just x -> ifM (liftIO $ finalizeIncremental x)
+					( return (True, Verified)
+					, return (False, UnVerified)
+					)
+				Nothing -> return (True, UnVerified)
 			, return (False, UnVerified)
 			)
 	
-	docopy' hdest hsrc sofar = do
+	docopy' iv hdest hsrc sofar = do
 		s <- S.hGet hsrc defaultChunkSize
 		if s == S.empty
 			then return ()
 			else do
 				let sofar' = addBytesProcessed sofar (S.length s)
 				S.hPut hdest s
+				maybe noop (flip updateIncremental s) iv
 				meterupdate sofar'
-				docopy' hdest hsrc sofar'
+				docopy' iv hdest hsrc sofar'
 
 	-- Leaves hdest and hsrc seeked to wherever the two diverge,
 	-- so typically hdest will be seeked to end, and hsrc to the same
 	-- position.
-	compareexisting hdest hsrc sofar = do
+	compareexisting iv hdest hsrc sofar = do
 		s <- S.hGet hdest defaultChunkSize
 		if s == S.empty
 			then return sofar
@@ -994,9 +1006,10 @@ fileCopier st src dest k meterupdate check =
 				s' <- getnoshort (S.length s) hsrc
 				if s == s'
 					then do
+						maybe noop (flip updateIncremental s) iv
 						let sofar' = addBytesProcessed sofar (S.length s)
 						meterupdate sofar'
-						compareexisting hdest hsrc sofar'
+						compareexisting iv hdest hsrc sofar'
 					else do
 						seekbefore hdest s
 						seekbefore hsrc s'
diff --git a/doc/todo/OPT__58_____34__bundle__34___get_+_check___40__of_checksum__41___in_a_single_operation/comment_10_695d1269ab20c66630ddfa2d8cbabbef._comment b/doc/todo/OPT__58_____34__bundle__34___get_+_check___40__of_checksum__41___in_a_single_operation/comment_10_695d1269ab20c66630ddfa2d8cbabbef._comment
new file mode 100644
index 000000000..4e754e0b8
--- /dev/null
+++ b/doc/todo/OPT__58_____34__bundle__34___get_+_check___40__of_checksum__41___in_a_single_operation/comment_10_695d1269ab20c66630ddfa2d8cbabbef._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 10"""
+ date="2021-02-10T19:48:58Z"
+ content="""
+Incremental hashing implemented for local git remotes.
+
+Next step should be a special remote, such as directory,
+that uses byteRetriever. Chunking and encryption will complicate them..
+"""]]
diff --git a/doc/todo/OPT__58_____34__bundle__34___get_+_check___40__of_checksum__41___in_a_single_operation/comment_9_4f4f4a42adafe52207ed32a5d20e94be._comment b/doc/todo/OPT__58_____34__bundle__34___get_+_check___40__of_checksum__41___in_a_single_operation/comment_9_4f4f4a42adafe52207ed32a5d20e94be._comment
index 8992a4c1d..befeac793 100644
--- a/doc/todo/OPT__58_____34__bundle__34___get_+_check___40__of_checksum__41___in_a_single_operation/comment_9_4f4f4a42adafe52207ed32a5d20e94be._comment
+++ b/doc/todo/OPT__58_____34__bundle__34___get_+_check___40__of_checksum__41___in_a_single_operation/comment_9_4f4f4a42adafe52207ed32a5d20e94be._comment
@@ -20,6 +20,6 @@ checksum.
 
 Urk: Using rsync currently protects against
 [[bugs/URL_key_potential_data_loss]], so the replacement would also need to
-deal with that. Probably by refusing to resume a partial transfer of an
-affected key. (Or it could just fall back to rsync for such keys.)
+deal with that. Eg, by comparing the temp file content with the start of
+the object when resuming.
 """]]

comment
diff --git a/doc/todo/OPT__58_____34__bundle__34___get_+_check___40__of_checksum__41___in_a_single_operation/comment_9_4f4f4a42adafe52207ed32a5d20e94be._comment b/doc/todo/OPT__58_____34__bundle__34___get_+_check___40__of_checksum__41___in_a_single_operation/comment_9_4f4f4a42adafe52207ed32a5d20e94be._comment
new file mode 100644
index 000000000..8992a4c1d
--- /dev/null
+++ b/doc/todo/OPT__58_____34__bundle__34___get_+_check___40__of_checksum__41___in_a_single_operation/comment_9_4f4f4a42adafe52207ed32a5d20e94be._comment
@@ -0,0 +1,25 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 9"""
+ date="2021-02-10T16:42:46Z"
+ content="""
+Incremental hashing implemented for transfers over ssh and tor.
+
+A good next step would be transfers to/from local git remotes.
+Currently those use rsync, or cp for CoW. It does not make sense to trust
+rsync's checksum verification here, because garbage in, garbage out --
+rsync doesn't know what the hash should be and will happily transfer a
+corrupted file. So instead, this would need to stop using rsync, and
+instead implement our own file to file copying with resuming and incremental
+hashing. Which would not be hard, and gets rid of the dependency on
+rsync besides (except for talking with really old git-annex-ssh).
+
+As for cp, CoW also suffers from GIGO, so I think the file will still
+need to be read, after its copied, to make sure it has the expected
+checksum.
+
+Urk: Using rsync currently protects against
+[[bugs/URL_key_potential_data_loss]], so the replacement would also need to
+deal with that. Probably by refusing to resume a partial transfer of an
+affected key. (Or it could just fall back to rsync for such keys.)
+"""]]

Added a comment
diff --git a/doc/todo/OPT__58_____34__bundle__34___get_+_check___40__of_checksum__41___in_a_single_operation/comment_9_b92774b0feec3049bf6aef89614543df._comment b/doc/todo/OPT__58_____34__bundle__34___get_+_check___40__of_checksum__41___in_a_single_operation/comment_9_b92774b0feec3049bf6aef89614543df._comment
new file mode 100644
index 000000000..6dbdad377
--- /dev/null
+++ b/doc/todo/OPT__58_____34__bundle__34___get_+_check___40__of_checksum__41___in_a_single_operation/comment_9_b92774b0feec3049bf6aef89614543df._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="yarikoptic"
+ avatar="http://cdn.libravatar.org/avatar/f11e9c84cb18d26a1748c33b48c924b4"
+ subject="comment 9"
+ date="2021-02-09T22:48:04Z"
+ content="""
+Thank you Joey!  In my particular/initial use case having it done only for \"native\" git annex downloads would already be great.  
+
+In the long term I do see us implementing it for `datalad` special remote.  Having it somehow just \"streaming\" into git annex would probably be the \"easiest on custom remotes\" and would provide most flexibility since it would be up to annex to use corresponding to backend checksum.  
+
+But I wonder if \"streaming\" is really needed -- through `TRANSFER STORE somekey tmpfile` annex already knows where the file downloaded so far is, most recently written blocks are likely to be in the FS cache, so may be it would suffice for a special remote to, in addition to PROGRESS, announce how many sequential bytes from the beginning have been downloaded already, and so if git-annex incrementally reads from the \"growing\" file it would just work? (I am not sure if Windows would allow for such \"collaborative\" use of the file where one process writes and another one reads)   Although I guess it would mean that `git-annex` would still need to trust external remote to not later change some earlier bytes in the file, so might be not sufficiently secure.  Thus probably true streaming/named pipe Ilya suggested would be needed.
+"""]]

comment
diff --git a/doc/todo/OPT__58_____34__bundle__34___get_+_check___40__of_checksum__41___in_a_single_operation/comment_8_593b8710c25bec1182409b36d6c44b4a._comment b/doc/todo/OPT__58_____34__bundle__34___get_+_check___40__of_checksum__41___in_a_single_operation/comment_8_593b8710c25bec1182409b36d6c44b4a._comment
new file mode 100644
index 000000000..e1b0bf777
--- /dev/null
+++ b/doc/todo/OPT__58_____34__bundle__34___get_+_check___40__of_checksum__41___in_a_single_operation/comment_8_593b8710c25bec1182409b36d6c44b4a._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 8"""
+ date="2021-02-09T21:04:12Z"
+ content="""
+The incrementalhash branch has a mostly complete implementation of
+incremental hashing on download, for retrieiving from git-annex
+remotes. And the Backend interface added for that should be easy to use in
+some special remotes as well. Let's start with that, worry about external
+special remotes only after the low-hanging fruit is picked.
+"""]]

comment
diff --git a/doc/todo/OPT__58_____34__bundle__34___get_+_check___40__of_checksum__41___in_a_single_operation/comment_7_48842fb1e006a05573ab34048db45c8b._comment b/doc/todo/OPT__58_____34__bundle__34___get_+_check___40__of_checksum__41___in_a_single_operation/comment_7_48842fb1e006a05573ab34048db45c8b._comment
new file mode 100644
index 000000000..76ef15db4
--- /dev/null
+++ b/doc/todo/OPT__58_____34__bundle__34___get_+_check___40__of_checksum__41___in_a_single_operation/comment_7_48842fb1e006a05573ab34048db45c8b._comment
@@ -0,0 +1,47 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 7"""
+ date="2021-02-09T16:31:47Z"
+ content="""
+I investigated feasability of a protocol extension that when 
+an external special remote enables it, means it always verifies a checksum
+itself before sending `TRANSFER-SUCCESS RETRIEVE`.
+
+Which checksum would be up to the special remote. Question is, would
+it need to be cryptographically secure, or would a CRC, sha1, or md5 suffice?
+
+annex.security.allow-unverified-downloads prevents download from special
+remotes when the content can't be verified, and that is to avoid a class of
+security holes (CVE-2018-10859). For the purposes of fixing that hole, sha1
+and md5 were considered good enough. The attacker does not control the
+original content, so a preimage attack won't work. The attacker has a
+gpg encrypted file they want to get decrypted, and they might be able to
+modify the file (eg appending junk, or messing with the gpg data in some
+way?) and cause a collision. I think sha1 and md5 are secure enough to
+avoid this attack. CRC is certianly not good enough. I'd be wary of md4
+since its preimage resistance is broken.
+
+So, doing this as a protocol extension would need to document that
+the hash needs to have preimage resistance, or be generally
+cryptographically secure. And then if a external special remote was using
+sha1 or whatever and it got sufficiently broken, it would be up to the
+maintainer of it to update it to stop using the protocol extension.
+
+I also looked at special remotes built into git-annex. Tahoe certianly
+does enough verification of downloads. Bittorrent doesn't because the
+torrent file is downloaded often w/o verification (magnet links could be
+verified enough maybe). Rsync usually uses a good enough checksum, but 
+can fall back to md4 or perhaps no checksum at all, and the attacker might
+control the rsync server, so the rsync special remote and also ssh
+remotes still need their own verification. Bup uses sha1 so does
+enough verification. All the rest don't.
+
+I think the question is, would this protocol extension really get used
+by any external special remotes? Anyone have an example of one? The
+alternative is to change the protocol so the downloaded content gets
+streamed to git-annex in some way, and have git-annex incrementally
+checksum as content comes in. Which really seems better all around, except
+probably a lot harder to implement, and using a small amount more CPU in
+cases where the external special remote is really doing its own
+checksumming.
+"""]]

Added a comment
diff --git a/doc/forum/Reverse_index_key_to_list_of_file_paths/comment_4_e54268d93837b3b8e216ec6af074f3c6._comment b/doc/forum/Reverse_index_key_to_list_of_file_paths/comment_4_e54268d93837b3b8e216ec6af074f3c6._comment
new file mode 100644
index 000000000..6c3db9d36
--- /dev/null
+++ b/doc/forum/Reverse_index_key_to_list_of_file_paths/comment_4_e54268d93837b3b8e216ec6af074f3c6._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="nguenthe@0f416ab0ba07a395eb8a0c85732e0105e4970e10"
+ nickname="nguenthe"
+ avatar="http://cdn.libravatar.org/avatar/0e245fd49594e98b19d4c57efcb134ad"
+ subject="comment 4"
+ date="2021-02-09T17:09:15Z"
+ content="""
+`git grep` might be just as slow as `find` in the end, but so far it has always been very fast for me. Maybe I just don't have a hyper-huge number of files.
+"""]]

Added a comment
diff --git a/doc/forum/Reverse_index_key_to_list_of_file_paths/comment_3_6b75bd75623004f05f609a39e95250ab._comment b/doc/forum/Reverse_index_key_to_list_of_file_paths/comment_3_6b75bd75623004f05f609a39e95250ab._comment
new file mode 100644
index 000000000..fc523c098
--- /dev/null
+++ b/doc/forum/Reverse_index_key_to_list_of_file_paths/comment_3_6b75bd75623004f05f609a39e95250ab._comment
@@ -0,0 +1,33 @@
+[[!comment format=mdwn
+ username="nguenthe@0f416ab0ba07a395eb8a0c85732e0105e4970e10"
+ nickname="nguenthe"
+ avatar="http://cdn.libravatar.org/avatar/0e245fd49594e98b19d4c57efcb134ad"
+ subject="comment 3"
+ date="2021-02-09T17:06:24Z"
+ content="""
+I just figured this out today!
+
+In v8 repos, every annexed file gets replaced by a text string like this:
+
+```
++/annex/objects/SHA256E-s320029--488e29f5584ba4e474db95aa42fbb58ddb92f2a59bc0b24a91171acb4d8f4828.png
+```
+
+((
+
+you can see them with `git log -p` or
+
+```
+$ git show HEAD:vlcsnap-2019-03-22-03h42m47s659.png
+/annex/objects/SHA256E-s320029--488e29f5584ba4e474db95aa42fbb58ddb92f2a59bc0b24a91171acb4d8f4828.png
+```
+
+))
+
+So to get the reverse pointer, you can use `git grep`:
+
+```
+$ git grep SHA256E-s320029--488e29f5584ba4e474db95aa42fbb58ddb92f2a59bc0b24a91171acb4d8f4828.png HEAD
+HEAD:vlcsnap-2019-03-22-03h42m47s659.png:/annex/objects/SHA256E-s320029--488e29f5584ba4e474db95aa42fbb58ddb92f2a59bc0b24a91171acb4d8f4828.png
+```
+"""]]

close
diff --git a/doc/todo/annex.thin_without_hardlinks.mdwn b/doc/todo/annex.thin_without_hardlinks.mdwn
index f33b8db94..912430714 100644
--- a/doc/todo/annex.thin_without_hardlinks.mdwn
+++ b/doc/todo/annex.thin_without_hardlinks.mdwn
@@ -14,4 +14,30 @@ Also some parts of git-annex's code, including `withObjectLoc`, assume
 that the .annex/objects is present, and so it would need to be changed
 to look at the work tree file. --[[Joey]]
 
-[[!tag needsthought]]
+> Git hook is not sufficient. Consider the case of "rm file; git checkout file"
+> Without hard links, if the only copy of the annex object was in that
+> deleted file, it can't be restored. Now, direct mode did have the same
+> problem, but it didn't support `git checkout`, so the user didn't have
+> reason to expect such a workflow to work.
+> 
+> So, I think this is not possible to implement in a way that won't
+> lead to users experiencing data loss when using it and doing 
+> perfectly normal git things like this.
+> 
+> (Although to be fair, annex.thin has its own data loss scenarios,
+> involving modifying a file potentially losing the only copy of
+> the old version. The difference, I think, is that with it,
+> you modify the file yourself and so lose the old version; the data
+> loss does not happen when you run git checkout or git pull!)
+> 
+> In the meantime,
+> git-annex has gotten support for directory special remotes with
+> import/export tree. This can be used instead, for use cases such as a
+> device with a FAT filesystem. The git-annex repo can live on another
+> filesystem that does support hard links or symlinks, or where using
+> double disk space is not as much of a problem, or can even be a bare
+> git repo. That syncs up with the FAT device through tree import and
+> export. Once content has been imported to the git-annex repo,
+> the user can delete files from the FAT device without losing data.
+> 
+> So this seems about as good as it can get. [[done]] --[[Joey]]

deal with cabal unpack not preserving execute bit
diff --git a/Build/Mans.hs b/Build/Mans.hs
index 9fb29d4a3..56183e30d 100644
--- a/Build/Mans.hs
+++ b/Build/Mans.hs
@@ -38,7 +38,9 @@ buildMans = do
 		if (Just srcm > destm)
 			then do
 				r <- system $ unwords
-					[ "./Build/mdwn2man"
+					-- Run with per because in some
+					-- cases it may not be executable.
+					[ "perl", "./Build/mdwn2man"
 					, progName src
 					, "1"
 					, src
diff --git a/doc/bugs/__91__Patch__93___fix___34__mdwn2man__58___cannot_execute_-_...__34__.mdwn b/doc/bugs/__91__Patch__93___fix___34__mdwn2man__58___cannot_execute_-_...__34__.mdwn
index 4a5a7bed6..d37e888c5 100644
--- a/doc/bugs/__91__Patch__93___fix___34__mdwn2man__58___cannot_execute_-_...__34__.mdwn
+++ b/doc/bugs/__91__Patch__93___fix___34__mdwn2man__58___cannot_execute_-_...__34__.mdwn
@@ -36,3 +36,5 @@ OpenBSD current
 Cabal 3.4.0.0
 
 git-annex master (commit `4e5a27841`)
+
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/__91__Patch__93___fix___34__mdwn2man__58___cannot_execute_-_...__34__/comment_1_cbfd460b55cc2b9df1a37936b71b881d._comment b/doc/bugs/__91__Patch__93___fix___34__mdwn2man__58___cannot_execute_-_...__34__/comment_1_cbfd460b55cc2b9df1a37936b71b881d._comment
new file mode 100644
index 000000000..026c52cf0
--- /dev/null
+++ b/doc/bugs/__91__Patch__93___fix___34__mdwn2man__58___cannot_execute_-_...__34__/comment_1_cbfd460b55cc2b9df1a37936b71b881d._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 1"""
+ date="2021-02-08T18:20:31Z"
+ content="""
+Reproduced by running `cabal unpack git-annex`. While the tarball on
+hackage does have execute bits, somehow cabal is not preserving them.
+Applied your patch, thanks.
+
+Cabal's ability to install anything more than a command into PATH is very
+limited, and also there's not really a good way to install man pages
+in a user's home directory in a way that will make man find them (ie,
+there's probably one way or less per OS, and all different). 
+So it's best to use the Makefile (from a git clone of the repo)
+if you want to install git-annex in a more complete manner, 
+ie system wide or generating a package of its files.
+"""]]

close as dup
diff --git a/doc/todo/Add_FAT_mode_without_double_using_disk_space.mdwn b/doc/todo/Add_FAT_mode_without_double_using_disk_space.mdwn
index ce47e57d4..2ea193f6b 100644
--- a/doc/todo/Add_FAT_mode_without_double_using_disk_space.mdwn
+++ b/doc/todo/Add_FAT_mode_without_double_using_disk_space.mdwn
@@ -3,3 +3,6 @@ At the FAT disks annex uses ajusted unlocked branch. Files use double space: in
 
 # As I wonder
 At such disks, with option annex.thin, annex uses only file tree for keeping content. Content of the files in the .git folder is wiped.
+
+> [[done]], dup of other todo, and I don't know how to avoid the problem
+> with git deleting the file. --[[Joey]]
diff --git a/doc/todo/Add_FAT_mode_without_double_using_disk_space/comment_1_133738096ed65997f2f4e9cb3332f957._comment b/doc/todo/Add_FAT_mode_without_double_using_disk_space/comment_1_133738096ed65997f2f4e9cb3332f957._comment
new file mode 100644
index 000000000..dbd06d7ad
--- /dev/null
+++ b/doc/todo/Add_FAT_mode_without_double_using_disk_space/comment_1_133738096ed65997f2f4e9cb3332f957._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 1"""
+ date="2021-02-08T18:17:00Z"
+ content="""
+This has the following problem: You run git pull. A file got deleted. git
+deletes the file in the repository directory. That was the only copy of the
+content, so it's now impossible to revert the deletion and get the file
+back, which you're supposed to be able to do.
+
+This is why git-annex has to either make a copy or hard link the file
+away for safekeeping.
+
+As already discussed in [[annex.thin without hardlinks]].
+"""]]

2021
diff --git a/doc/thanks.mdwn b/doc/thanks.mdwn
index f9d7c6c82..3a15d3bbe 100644
--- a/doc/thanks.mdwn
+++ b/doc/thanks.mdwn
@@ -31,7 +31,7 @@ tips, user support, etc. Two names that come to mind are Anarcat and
 CandyAngel. John Lawrence made the logo. And many others have
 contributed good bug reports and great ideas.
 
-## financial support, 2019-2020
+## financial support, 2019-2021
 
 <img alt="McGill logo" src="https://mcgill.ca/hbhl/sites/all/themes/moriarty/images/logo-red.svg" width=100>
 <img alt="Neurohub" src="https://joeyh.name/blog/pics/neurohub.png" width=100>

avoid making absolute git remote path relative
When a git remote is configured with an absolute path, use that path,
rather than making it relative. If it's configured with a relative path,
use that.
Git.Construct.fromPath changed to preserve the path as-is,
rather than making it absolute. And Annex.new changed to not
convert the path to relative. Instead, Git.CurrentRepo.get
generates a relative path.
A few things that used fromAbsPath unncessarily were changed in passing to
use fromPath instead. I'm seeing fromAbsPath as a security check,
while before it was being used in some cases when the path was
known absolute already. It may be that fromAbsPath is not really needed,
but only git-annex-shell uses it now, and I'm not 100% sure that there's
not some input that would cause a relative path to be used, opening a
security hole, without the security check. So left it as-is.
Test suite passes and strace shows the configured remote url is used
unchanged in the path into it. I can't be 100% sure there's not some code
somewhere that takes an absolute path to the repo and converts it to
relative and uses it, but it seems pretty unlikely that the code paths used
for a git remote would call such code. One place I know of is gitAnnexLink,
but I'm pretty sure that git remotes never deal with annex symlinks. If
that did get called, it generates a path relative to cwd, which would have
been wrong before this change as well, when operating on a remote.
diff --git a/Annex.hs b/Annex.hs
index dc3466e3e..02d4fa035 100644
--- a/Annex.hs
+++ b/Annex.hs
@@ -247,7 +247,7 @@ newState c r = do
  - any necessary git repo fixups. -}
 new :: Git.Repo -> IO AnnexState
 new r = do
-	r' <- Git.Config.read =<< Git.relPath r
+	r' <- Git.Config.read r
 	let c = extractGitConfig FromGitConfig r'
 	newState c =<< fixupRepo r' c
 
diff --git a/CHANGELOG b/CHANGELOG
index 09043473f..2667075cc 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -20,6 +20,8 @@ git-annex (8.20210128) UNRELEASED; urgency=medium
     transfer progress consistently enough.
   * When annex.stalldetection is not enabled and a likely stall is
     detected, display a suggestion to enable it.
+  * When a git remote is configured with an absolute path, use that
+    path, rather than making it relative.
 
  -- Joey Hess <id@joeyh.name>  Thu, 28 Jan 2021 12:34:32 -0400
 
diff --git a/Command/Map.hs b/Command/Map.hs
index 4f3419001..7af7db08c 100644
--- a/Command/Map.hs
+++ b/Command/Map.hs
@@ -178,7 +178,7 @@ absRepo reference r
 	| Git.repoIsUrl reference = return $ Git.Construct.localToUrl reference r
 	| Git.repoIsUrl r = return r
 	| otherwise = liftIO $ do
-		r' <- Git.Construct.fromAbsPath =<< absPath (Git.repoPath r)
+		r' <- Git.Construct.fromPath =<< absPath (Git.repoPath r)
 		r'' <- safely $ flip Annex.eval Annex.gitRepo =<< Annex.new r'
 		return (fromMaybe r' r'')
 
diff --git a/Git/Construct.hs b/Git/Construct.hs
index de896bbe5..af7bb0557 100644
--- a/Git/Construct.hs
+++ b/Git/Construct.hs
@@ -57,35 +57,34 @@ fromCwd = getCurrentDirectory >>= seekUp
 
 {- Local Repo constructor, accepts a relative or absolute path. -}
 fromPath :: RawFilePath -> IO Repo
-fromPath dir = fromAbsPath =<< absPath dir
+fromPath dir
+	-- When dir == "foo/.git", git looks for "foo/.git/.git",
+	-- and failing that, uses "foo" as the repository.
+	| (P.pathSeparator `B.cons` ".git") `B.isSuffixOf` canondir =
+		ifM (doesDirectoryExist $ fromRawFilePath dir </> ".git")
+			( ret dir
+			, ret (P.takeDirectory canondir)
+			)
+	| otherwise = ifM (doesDirectoryExist (fromRawFilePath dir))
+		( checkGitDirFile dir >>= maybe (ret dir) (pure . newFrom)
+		-- git falls back to dir.git when dir doesn't
+		-- exist, as long as dir didn't end with a
+		-- path separator
+		, if dir == canondir
+			then ret (dir <> ".git")
+			else ret dir
+		)
+  where
+	ret = pure . newFrom . LocalUnknown
+	canondir = P.dropTrailingPathSeparator dir
 
 {- Local Repo constructor, requires an absolute path to the repo be
  - specified. -}
 fromAbsPath :: RawFilePath -> IO Repo
 fromAbsPath dir
-	| absoluteGitPath dir = hunt
+	| absoluteGitPath dir = fromPath dir
 	| otherwise =
 		error $ "internal error, " ++ show dir ++ " is not absolute"
-  where
-	ret = pure . newFrom . LocalUnknown
-	canondir = P.dropTrailingPathSeparator dir
-	{- When dir == "foo/.git", git looks for "foo/.git/.git",
-	 - and failing that, uses "foo" as the repository. -}
-	hunt
-		| (P.pathSeparator `B.cons` ".git") `B.isSuffixOf` canondir =
-			ifM (doesDirectoryExist $ fromRawFilePath dir </> ".git")
-				( ret dir
-				, ret (P.takeDirectory canondir)
-				)
-		| otherwise = ifM (doesDirectoryExist (fromRawFilePath dir))
-			( checkGitDirFile dir >>= maybe (ret dir) (pure . newFrom)
-			-- git falls back to dir.git when dir doesn't
-			-- exist, as long as dir didn't end with a
-			-- path separator
-			, if dir == canondir
-				then ret (dir <> ".git")
-				else ret dir
-			)
 
 {- Construct a Repo for a remote's url.
  -
diff --git a/Git/CurrentRepo.hs b/Git/CurrentRepo.hs
index 25bdc5c63..9261eabca 100644
--- a/Git/CurrentRepo.hs
+++ b/Git/CurrentRepo.hs
@@ -10,6 +10,7 @@
 module Git.CurrentRepo where
 
 import Common
+import Git
 import Git.Types
 import Git.Construct
 import qualified Git.Config
@@ -46,12 +47,12 @@ get = do
 	wt <- maybe (worktree (location r)) Just
 		<$> getpathenvprefix "GIT_WORK_TREE" prefix
 	case wt of
-		Nothing -> return r
+		Nothing -> relPath r
 		Just d -> do
 			curr <- R.getCurrentDirectory
 			unless (d `dirContains` curr) $
 				setCurrentDirectory (fromRawFilePath d)
-			return $ addworktree wt r
+			relPath $ addworktree wt r
   where
 	getpathenv s = do
 		v <- getEnv s
diff --git a/Git/Repair.hs b/Git/Repair.hs
index 034d7e98d..6d9aeec99 100644
--- a/Git/Repair.hs
+++ b/Git/Repair.hs
@@ -105,7 +105,7 @@ retrieveMissingObjects missing referencerepo r
 	| otherwise = withTmpDir "tmprepo" $ \tmpdir -> do
 		unlessM (boolSystem "git" [Param "init", File tmpdir]) $
 			error $ "failed to create temp repository in " ++ tmpdir
-		tmpr <- Config.read =<< Construct.fromAbsPath (toRawFilePath tmpdir)
+		tmpr <- Config.read =<< Construct.fromPath (toRawFilePath tmpdir)
 		rs <- Construct.fromRemotes r
 		stillmissing <- pullremotes tmpr rs fetchrefstags missing
 		if S.null (knownMissing stillmissing)
diff --git a/Remote/Bup.hs b/Remote/Bup.hs
index 6ba638a2d..2da6642d2 100644
--- a/Remote/Bup.hs
+++ b/Remote/Bup.hs
@@ -287,11 +287,11 @@ bup2GitRemote :: BupRepo -> IO Git.Repo
 bup2GitRemote "" = do
 	-- bup -r "" operates on ~/.bup
 	h <- myHomeDir
-	Git.Construct.fromAbsPath $ toRawFilePath $ h </> ".bup"
+	Git.Construct.fromPath $ toRawFilePath $ h </> ".bup"
 bup2GitRemote r
 	| bupLocal r = 
 		if "/" `isPrefixOf` r
-			then Git.Construct.fromAbsPath (toRawFilePath r)
+			then Git.Construct.fromPath (toRawFilePath r)
 			else giveup "please specify an absolute path"
 	| otherwise = Git.Construct.fromUrl $ "ssh://" ++ host ++ slash dir
   where
diff --git a/doc/bugs/git-annex_get__58___createDirectory__58___does_not_exist.mdwn b/doc/bugs/git-annex_get__58___createDirectory__58___does_not_exist.mdwn
index 0b64b968e..4235bf399 100644
--- a/doc/bugs/git-annex_get__58___createDirectory__58___does_not_exist.mdwn
+++ b/doc/bugs/git-annex_get__58___createDirectory__58___does_not_exist.mdwn
@@ -29,3 +29,7 @@ git-annex is critical infrastructure for me. There is no day without it. Thx muc
 
 
 [[!tag projects/datalad]]
+
+> So there's an OSX bug here, and git-annex has been made to use
+> an absolute path to a remote when it has one, which can be used to work
+> around the OSX bug. [[done]] --[[Joey]]
diff --git a/doc/bugs/git-annex_get__58___createDirectory__58___does_not_exist/comment_7_2899ef72aa2a5488eb945d14f7a2d76e._comment b/doc/bugs/git-annex_get__58___createDirectory__58___does_not_exist/comment_7_2899ef72aa2a5488eb945d14f7a2d76e._comment
new file mode 100644
index 000000000..fc367bb9c
--- /dev/null
+++ b/doc/bugs/git-annex_get__58___createDirectory__58___does_not_exist/comment_7_2899ef72aa2a5488eb945d14f7a2d76e._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 7"""
+ date="2021-02-08T15:54:58Z"
+ content="""
+Agreed, what you show in the stackoverflow post can only be an OSX bug.
+
+Using a relative path for the current repository does avoid using long
+absolute paths, and also has a minor benefit of letting the repository be
+moved while git-annex is running and it still accessing the right files.
+
+Neither benefit applies to the paths to remotes. I think the only
+reason relative paths are being used for them is that the same code
+is used to operate on them as on the local repository.
+
+I've made some changes that will make it use absolute paths when the
+remote has an absolute path.
+"""]]

Added a comment: why relative path?
diff --git a/doc/bugs/git-annex_get__58___createDirectory__58___does_not_exist/comment_6_b8f96a403990a125bf181f0ce8bea44e._comment b/doc/bugs/git-annex_get__58___createDirectory__58___does_not_exist/comment_6_b8f96a403990a125bf181f0ce8bea44e._comment
new file mode 100644
index 000000000..94431144a
--- /dev/null
+++ b/doc/bugs/git-annex_get__58___createDirectory__58___does_not_exist/comment_6_b8f96a403990a125bf181f0ce8bea44e._comment
@@ -0,0 +1,72 @@
+[[!comment format=mdwn
+ username="yarikoptic"
+ avatar="http://cdn.libravatar.org/avatar/f11e9c84cb18d26a1748c33b48c924b4"
+ subject="why relative path?"
+ date="2021-02-08T14:47:42Z"
+ content="""
+I feel it is OS (OSX bug), does not reproduce on newer 11.1 (appveyor has 10.15.7), [asked on SO](https://stackoverflow.com/questions/66103552/osx-mkdir-tmp-dir-no-such-file-or-directory-under-private-while-ls-can-l) anyways with minimalistic example.  I believe it is the `tmp -> private/tmp` somehow throws it off.
+
+<details>
+<summary>But I also wonder why git-annex uses relative path for get whenever remote is specified via an absolute one?</summary>
+
+```shell
+bash-3.2$ cd /private/var/folders/5s/g225f6nd6jl4g8tshbh1ltk40000gn/T/datalad_temp_test_get_recurse_dirs7eiohcer
+bash-3.2$ cat .git/config
+[core]
+        repositoryformatversion = 0
+        filemode = true
+        bare = false
+        logallrefupdates = true
+        ignorecase = true
+        precomposeunicode = true
+[remote \\"origin\\"]
+        url = /var/folders/5s/g225f6nd6jl4g8tshbh1ltk40000gn/T/datalad_temp_tree_test_get_recurse_dirsfciy781u
+        fetch = +refs/heads/*:refs/remotes/origin/*
+        annex-uuid = 52043a4d-fab3-4661-a8aa-904cd780c804
+[branch \\"dl-test-branch\\"]
+        remote = origin
+        merge = refs/heads/dl-test-branch
+[annex \\"security\\"]
+        allowed-url-schemes = http https file
+        allowed-http-addresses = all
+[annex]
+        uuid = f40f35d9-cd79-4258-9f25-bdeb56303f94
+        version = 8
+[filter \\"annex\\"]
+        smudge = git-annex smudge -- %f
+        clean = git-annex smudge --clean -- %f
+bash-3.2$ git annex get --debug --from origin subdir/file2.txt
+[2021-02-08 08:37:39.159007] process [10170] read: git [\\"--git-dir=.git\\",\\"--work-tree=.\\",\\"--literal-pathspecs\\",\\"show-ref\\",\\"git-annex\\"]
+[2021-02-08 08:37:39.164531] process [10170] done ExitSuccess
+[2021-02-08 08:37:39.165453] process [10171] read: git [\\"--git-dir=.git\\",\\"--work-tree=.\\",\\"--literal-pathspecs\\",\\"show-ref\\",\\"--hash\\",\\"refs/heads/git-annex\\"]
+[2021-02-08 08:37:39.169315] process [10171] done ExitSuccess
+[2021-02-08 08:37:39.170596] process [10172] read: git [\\"--git-dir=.git\\",\\"--work-tree=.\\",\\"--literal-pathspecs\\",\\"log\\",\\"refs/heads/git-annex..250f87f912fab3d2081ef0ccd02ffc35fd7a97a7\\",\\"--pretty=%H\\",\\"-n1\\"]
+[2021-02-08 08:37:39.177178] process [10172] done ExitSuccess
+[2021-02-08 08:37:39.178303] process [10173] chat: git [\\"--git-dir=.git\\",\\"--work-tree=.\\",\\"--literal-pathspecs\\",\\"cat-file\\",\\"--batch\\"]
+[2021-02-08 08:37:39.179112] process [10174] chat: git [\\"--git-dir=.git\\",\\"--work-tree=.\\",\\"--literal-pathspecs\\",\\"cat-file\\",\\"--batch-check=%(objectname) %(objecttype) %(objectsize)\\"]
+[2021-02-08 08:37:39.183428] process [10175] read: git [\\"config\\",\\"--null\\",\\"--list\\"]
+[2021-02-08 08:37:39.188091] process [10175] done ExitSuccess
+[2021-02-08 08:37:39.195372] process [10176] read: git [\\"--git-dir=.git\\",\\"--work-tree=.\\",\\"--literal-pathspecs\\",\\"symbolic-ref\\",\\"-q\\",\\"HEAD\\"]
+[2021-02-08 08:37:39.198517] process [10176] done ExitSuccess
+[2021-02-08 08:37:39.199328] process [10177] read: git [\\"--git-dir=.git\\",\\"--work-tree=.\\",\\"--literal-pathspecs\\",\\"show-ref\\",\\"refs/heads/dl-test-branch\\"]
+[2021-02-08 08:37:39.202993] process [10177] done ExitSuccess
+[2021-02-08 08:37:39.20432] process [10178] read: git [\\"--git-dir=.git\\",\\"--work-tree=.\\",\\"--literal-pathspecs\\",\\"ls-files\\",\\"--stage\\",\\"-z\\",\\"--\\",\\"subdir/file2.txt\\"]
+[2021-02-08 08:37:39.205302] process [10179] chat: git [\\"--git-dir=.git\\",\\"--work-tree=.\\",\\"--literal-pathspecs\\",\\"cat-file\\",\\"--batch-check=%(objectname) %(objecttype) %(objectsize)\\",\\"--buffer\\"]
+[2021-02-08 08:37:39.208369] process [10180] chat: git [\\"--git-dir=.git\\",\\"--work-tree=.\\",\\"--literal-pathspecs\\",\\"cat-file\\",\\"--batch=%(objectname) %(objecttype) %(objectsize)\\",\\"--buffer\\"]
+[2021-02-08 08:37:39.209513] process [10181] chat: git [\\"--git-dir=.git\\",\\"--work-tree=.\\",\\"--literal-pathspecs\\",\\"cat-file\\",\\"--batch=%(objectname) %(objecttype) %(objectsize)\\",\\"--buffer\\"]
+get subdir/file2.txt (from origin...)
+  ../../../../../../../var/folders/5s/g225f6nd6jl4g8tshbh1ltk40000gn/T/datalad_temp_tree_test_get_recurse_dirsfciy781u/.git/annex: createDirectory: does not exist (No such file or directory)
+failed
+[2021-02-08 08:37:39.218675] process [10181] done ExitSuccess
+[2021-02-08 08:37:39.218748] process [10180] done ExitSuccess
+[2021-02-08 08:37:39.218781] process [10179] done ExitSuccess
+[2021-02-08 08:37:39.218806] process [10178] done ExitSuccess
+git-annex: get: 1 failed
+
+```
+</details>
+
+IIRC it might have been done to minimize the path length so we have a better chance to not hit limits.  But in this case, if anything - it makes it only longer.
+
+PS initially posted with another \"wisdom\" that relative path was off but only then spotted that it was `/var` vs `/private/var` ;)
+"""]]

removed
diff --git a/doc/bugs/git-annex_get__58___createDirectory__58___does_not_exist/comment_6_7dca0e05f1ff074d828bf95318914618._comment b/doc/bugs/git-annex_get__58___createDirectory__58___does_not_exist/comment_6_7dca0e05f1ff074d828bf95318914618._comment
deleted file mode 100644
index 3bf7e7390..000000000
--- a/doc/bugs/git-annex_get__58___createDirectory__58___does_not_exist/comment_6_7dca0e05f1ff074d828bf95318914618._comment
+++ /dev/null
@@ -1,113 +0,0 @@
-[[!comment format=mdwn
- username="yarikoptic"
- avatar="http://cdn.libravatar.org/avatar/f11e9c84cb18d26a1748c33b48c924b4"
- subject="comment 6"
- date="2021-02-08T14:44:35Z"
- content="""
-I feel it is OS (OSX bug), does not reproduce on newer 11.1 (appveyor has 10.15.7), [asked on SO](https://stackoverflow.com/questions/66103552/osx-mkdir-tmp-dir-no-such-file-or-directory-under-private-while-ls-can-l) anyways with minimalistic example.  I believe it is the `tmp -> private/tmp` somehow throws it off.
-
-<details>
-<summary>But I also wonder why git-annex uses relative path for get whenever remote is specified via an absolute one?</summary> 
-
-```shell
-bash-3.2$ cd /private/var/folders/5s/g225f6nd6jl4g8tshbh1ltk40000gn/T/datalad_temp_test_get_recurse_dirs7eiohcer
-bash-3.2$ cat .git/config
-[core]  
-        repositoryformatversion = 0
-        filemode = true
-        bare = false
-        logallrefupdates = true
-        ignorecase = true
-        precomposeunicode = true
-[remote \"origin\"]
-        url = /var/folders/5s/g225f6nd6jl4g8tshbh1ltk40000gn/T/datalad_temp_tree_test_get_recurse_dirsfciy781u
-        fetch = +refs/heads/*:refs/remotes/origin/*
-        annex-uuid = 52043a4d-fab3-4661-a8aa-904cd780c804
-[branch \"dl-test-branch\"]
-        remote = origin
-        merge = refs/heads/dl-test-branch
-[annex \"security\"]
-        allowed-url-schemes = http https file
-        allowed-http-addresses = all
-[annex] 
-        uuid = f40f35d9-cd79-4258-9f25-bdeb56303f94
-        version = 8
-[filter \"annex\"]
-        smudge = git-annex smudge -- %f
-        clean = git-annex smudge --clean -- %f
-bash-3.2$ git annex get --debug --from origin subdir/file2.txt
-[2021-02-08 08:37:39.159007] process [10170] read: git [\"--git-dir=.git\",\"--work-tree=.\",\"--literal-pathspecs\",\"show-ref\",\"git-annex\"]
-[2021-02-08 08:37:39.164531] process [10170] done ExitSuccess
-[2021-02-08 08:37:39.165453] process [10171] read: git [\"--git-dir=.git\",\"--work-tree=.\",\"--literal-pathspecs\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
-[2021-02-08 08:37:39.169315] process [10171] done ExitSuccess
-[2021-02-08 08:37:39.170596] process [10172] read: git [\"--git-dir=.git\",\"--work-tree=.\",\"--literal-pathspecs\",\"log\",\"refs/heads/git-annex..250f87f912fab3d2081ef0ccd02ffc35fd7a97a7\",\"--pretty=%H\",\"-n1\"]
-[2021-02-08 08:37:39.177178] process [10172] done ExitSuccess
-[2021-02-08 08:37:39.178303] process [10173] chat: git [\"--git-dir=.git\",\"--work-tree=.\",\"--literal-pathspecs\",\"cat-file\",\"--batch\"]
-[2021-02-08 08:37:39.179112] process [10174] chat: git [\"--git-dir=.git\",\"--work-tree=.\",\"--literal-pathspecs\",\"cat-file\",\"--batch-check=%(objectname) %(objecttype) %(objectsize)\"]
-[2021-02-08 08:37:39.183428] process [10175] read: git [\"config\",\"--null\",\"--list\"]
-[2021-02-08 08:37:39.188091] process [10175] done ExitSuccess
-[2021-02-08 08:37:39.195372] process [10176] read: git [\"--git-dir=.git\",\"--work-tree=.\",\"--literal-pathspecs\",\"symbolic-ref\",\"-q\",\"HEAD\"]
-[2021-02-08 08:37:39.198517] process [10176] done ExitSuccess
-[2021-02-08 08:37:39.199328] process [10177] read: git [\"--git-dir=.git\",\"--work-tree=.\",\"--literal-pathspecs\",\"show-ref\",\"refs/heads/dl-test-branch\"]
-[2021-02-08 08:37:39.202993] process [10177] done ExitSuccess
-[2021-02-08 08:37:39.20432] process [10178] read: git [\"--git-dir=.git\",\"--work-tree=.\",\"--literal-pathspecs\",\"ls-files\",\"--stage\",\"-z\",\"--\",\"subdir/file2.txt\"]
-[2021-02-08 08:37:39.205302] process [10179] chat: git [\"--git-dir=.git\",\"--work-tree=.\",\"--literal-pathspecs\",\"cat-file\",\"--batch-check=%(objectname) %(objecttype) %(objectsize)\",\"--buffer\"]
-[2021-02-08 08:37:39.208369] process [10180] chat: git [\"--git-dir=.git\",\"--work-tree=.\",\"--literal-pathspecs\",\"cat-file\",\"--batch=%(objectname) %(objecttype) %(objectsize)\",\"--buffer\"]
-[2021-02-08 08:37:39.209513] process [10181] chat: git [\"--git-dir=.git\",\"--work-tree=.\",\"--literal-pathspecs\",\"cat-file\",\"--batch=%(objectname) %(objecttype) %(objectsize)\",\"--buffer\"]
-get subdir/file2.txt (from origin...)
-  ../../../../../../../var/folders/5s/g225f6nd6jl4g8tshbh1ltk40000gn/T/datalad_temp_tree_test_get_recurse_dirsfciy781u/.git/annex: createDirectory: does not exist (No such file or directory)
-failed
-[2021-02-08 08:37:39.218675] process [10181] done ExitSuccess
-[2021-02-08 08:37:39.218748] process [10180] done ExitSuccess
-[2021-02-08 08:37:39.218781] process [10179] done ExitSuccess
-[2021-02-08 08:37:39.218806] process [10178] done ExitSuccess
-git-annex: get: 1 failed
-
-```
-</details>
-
-IIRC it might have been done to minimize the path length so we have a better chance to not hit limits.  But in this case, if anything - it makes it only longer, and if was actually to create a relative path, it should have not had that middle `../../../var/folders/5s/` since it is common to both:
-
-```
-bash-3.2$ pwd
-/private/var/folders/5s/g225f6nd6jl4g8tshbh1ltk40000gn/T/datalad_temp_test_get_recurse_dirs7eiohcer
-bash-3.2$ git config remote.origin.url
-/var/folders/5s/g225f6nd6jl4g8tshbh1ltk40000gn/T/datalad_temp_tree_test_get_recurse_dirsfciy781u
-bash-3.2$ git annex whereis subdir/file2.txt 
-whereis subdir/file2.txt (1 copy) 
-        52043a4d-fab3-4661-a8aa-904cd780c804 -- appveyor@worker-628-003.shared:/private/var/folders/5s/g225f6nd6jl4g8tshbh1ltk40000gn/T/datalad_temp_tree_test_get_recurse_dirsfciy781u [origin]
-ok
-bash-3.2$ git annex get subdir/file2.txt
-get subdir/file2.txt (from origin...) 
-  ../../../../../../../var/folders/5s/g225f6nd6jl4g8tshbh1ltk40000gn/T/datalad_temp_tree_test_get_recurse_dirsfciy781u/.git/annex: createDirectory: does not exist (No such file or directory)
-
-  Unable to access these remotes: origin
-
-  Try making some of these remotes available:
-        52043a4d-fab3-4661-a8aa-904cd780c804 -- appveyor@worker-628-003.shared:/private/var/folders/5s/g225f6nd6jl4g8tshbh1ltk40000gn/T/datalad_temp_tree_test_get_recurse_dirsfciy781u [origin]
-failed
-git-annex: get: 1 failed
-bash-3.2$ ls -l ../../../g225f6nd6jl4g8tshbh1ltk40000gn/T/datalad_temp_test_get_recurse_dirs7eiohcer/.git/annex/
-total 32
--rw-r--r--  1 appveyor  staff  681 Feb  8 08:09 index
--rw-r--r--  1 appveyor  staff   41 Feb  8 08:09 index.lck
-drwxr-xr-x  2 appveyor  staff   64 Feb  8 08:09 journal
--rw-r--r--  1 appveyor  staff    0 Feb  8 08:09 journal.lck
--rw-r--r--  1 appveyor  staff   71 Feb  8 08:09 mergedrefs
--rw-r--r--  1 appveyor  staff    0 Feb  8 08:37 move.lck
--rw-r--r--  1 appveyor  staff    0 Feb  8 08:37 move.log
--rw-r--r--  1 appveyor  staff    0 Feb  8 08:09 othertmp.lck
--rw-r--r--  1 appveyor  staff    0 Feb  8 08:09 sentinal
--rw-r--r--  1 appveyor  staff   34 Feb  8 08:09 sentinal.cache
--rw-r--r--  1 appveyor  staff    0 Feb  8 08:09 smudge.lck
-drwxr-xr-x  2 appveyor  staff   64 Feb  8 08:09 tmp
-drwxr-xr-x  4 appveyor  staff  128 Feb  8 08:09 transfer
-```
-
-and if it didn't escape all the way to the `/`, mkdir would have even worked:
-```
-bash-3.2$ mkdir ../../../g225f6nd6jl4g8tshbh1ltk40000gn/T/datalad_temp_test_get_recurse_dirs7eiohcer/.git/annex/123
-bash-3.2$ 
-```
-```
-"""]]

Added a comment
diff --git a/doc/bugs/git-annex_get__58___createDirectory__58___does_not_exist/comment_6_7dca0e05f1ff074d828bf95318914618._comment b/doc/bugs/git-annex_get__58___createDirectory__58___does_not_exist/comment_6_7dca0e05f1ff074d828bf95318914618._comment
new file mode 100644
index 000000000..3bf7e7390
--- /dev/null
+++ b/doc/bugs/git-annex_get__58___createDirectory__58___does_not_exist/comment_6_7dca0e05f1ff074d828bf95318914618._comment
@@ -0,0 +1,113 @@
+[[!comment format=mdwn
+ username="yarikoptic"
+ avatar="http://cdn.libravatar.org/avatar/f11e9c84cb18d26a1748c33b48c924b4"
+ subject="comment 6"
+ date="2021-02-08T14:44:35Z"
+ content="""
+I feel it is OS (OSX bug), does not reproduce on newer 11.1 (appveyor has 10.15.7), [asked on SO](https://stackoverflow.com/questions/66103552/osx-mkdir-tmp-dir-no-such-file-or-directory-under-private-while-ls-can-l) anyways with minimalistic example.  I believe it is the `tmp -> private/tmp` somehow throws it off.
+
+<details>
+<summary>But I also wonder why git-annex uses relative path for get whenever remote is specified via an absolute one?</summary> 
+
+```shell
+bash-3.2$ cd /private/var/folders/5s/g225f6nd6jl4g8tshbh1ltk40000gn/T/datalad_temp_test_get_recurse_dirs7eiohcer
+bash-3.2$ cat .git/config
+[core]  
+        repositoryformatversion = 0
+        filemode = true
+        bare = false
+        logallrefupdates = true
+        ignorecase = true
+        precomposeunicode = true
+[remote \"origin\"]
+        url = /var/folders/5s/g225f6nd6jl4g8tshbh1ltk40000gn/T/datalad_temp_tree_test_get_recurse_dirsfciy781u
+        fetch = +refs/heads/*:refs/remotes/origin/*
+        annex-uuid = 52043a4d-fab3-4661-a8aa-904cd780c804
+[branch \"dl-test-branch\"]
+        remote = origin
+        merge = refs/heads/dl-test-branch
+[annex \"security\"]
+        allowed-url-schemes = http https file
+        allowed-http-addresses = all
+[annex] 
+        uuid = f40f35d9-cd79-4258-9f25-bdeb56303f94
+        version = 8
+[filter \"annex\"]
+        smudge = git-annex smudge -- %f
+        clean = git-annex smudge --clean -- %f
+bash-3.2$ git annex get --debug --from origin subdir/file2.txt
+[2021-02-08 08:37:39.159007] process [10170] read: git [\"--git-dir=.git\",\"--work-tree=.\",\"--literal-pathspecs\",\"show-ref\",\"git-annex\"]
+[2021-02-08 08:37:39.164531] process [10170] done ExitSuccess
+[2021-02-08 08:37:39.165453] process [10171] read: git [\"--git-dir=.git\",\"--work-tree=.\",\"--literal-pathspecs\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+[2021-02-08 08:37:39.169315] process [10171] done ExitSuccess
+[2021-02-08 08:37:39.170596] process [10172] read: git [\"--git-dir=.git\",\"--work-tree=.\",\"--literal-pathspecs\",\"log\",\"refs/heads/git-annex..250f87f912fab3d2081ef0ccd02ffc35fd7a97a7\",\"--pretty=%H\",\"-n1\"]
+[2021-02-08 08:37:39.177178] process [10172] done ExitSuccess
+[2021-02-08 08:37:39.178303] process [10173] chat: git [\"--git-dir=.git\",\"--work-tree=.\",\"--literal-pathspecs\",\"cat-file\",\"--batch\"]
+[2021-02-08 08:37:39.179112] process [10174] chat: git [\"--git-dir=.git\",\"--work-tree=.\",\"--literal-pathspecs\",\"cat-file\",\"--batch-check=%(objectname) %(objecttype) %(objectsize)\"]
+[2021-02-08 08:37:39.183428] process [10175] read: git [\"config\",\"--null\",\"--list\"]
+[2021-02-08 08:37:39.188091] process [10175] done ExitSuccess
+[2021-02-08 08:37:39.195372] process [10176] read: git [\"--git-dir=.git\",\"--work-tree=.\",\"--literal-pathspecs\",\"symbolic-ref\",\"-q\",\"HEAD\"]
+[2021-02-08 08:37:39.198517] process [10176] done ExitSuccess
+[2021-02-08 08:37:39.199328] process [10177] read: git [\"--git-dir=.git\",\"--work-tree=.\",\"--literal-pathspecs\",\"show-ref\",\"refs/heads/dl-test-branch\"]
+[2021-02-08 08:37:39.202993] process [10177] done ExitSuccess
+[2021-02-08 08:37:39.20432] process [10178] read: git [\"--git-dir=.git\",\"--work-tree=.\",\"--literal-pathspecs\",\"ls-files\",\"--stage\",\"-z\",\"--\",\"subdir/file2.txt\"]
+[2021-02-08 08:37:39.205302] process [10179] chat: git [\"--git-dir=.git\",\"--work-tree=.\",\"--literal-pathspecs\",\"cat-file\",\"--batch-check=%(objectname) %(objecttype) %(objectsize)\",\"--buffer\"]
+[2021-02-08 08:37:39.208369] process [10180] chat: git [\"--git-dir=.git\",\"--work-tree=.\",\"--literal-pathspecs\",\"cat-file\",\"--batch=%(objectname) %(objecttype) %(objectsize)\",\"--buffer\"]
+[2021-02-08 08:37:39.209513] process [10181] chat: git [\"--git-dir=.git\",\"--work-tree=.\",\"--literal-pathspecs\",\"cat-file\",\"--batch=%(objectname) %(objecttype) %(objectsize)\",\"--buffer\"]
+get subdir/file2.txt (from origin...)
+  ../../../../../../../var/folders/5s/g225f6nd6jl4g8tshbh1ltk40000gn/T/datalad_temp_tree_test_get_recurse_dirsfciy781u/.git/annex: createDirectory: does not exist (No such file or directory)
+failed
+[2021-02-08 08:37:39.218675] process [10181] done ExitSuccess
+[2021-02-08 08:37:39.218748] process [10180] done ExitSuccess
+[2021-02-08 08:37:39.218781] process [10179] done ExitSuccess
+[2021-02-08 08:37:39.218806] process [10178] done ExitSuccess
+git-annex: get: 1 failed
+
+```
+</details>
+
+IIRC it might have been done to minimize the path length so we have a better chance to not hit limits.  But in this case, if anything - it makes it only longer, and if was actually to create a relative path, it should have not had that middle `../../../var/folders/5s/` since it is common to both:
+
+```
+bash-3.2$ pwd
+/private/var/folders/5s/g225f6nd6jl4g8tshbh1ltk40000gn/T/datalad_temp_test_get_recurse_dirs7eiohcer
+bash-3.2$ git config remote.origin.url
+/var/folders/5s/g225f6nd6jl4g8tshbh1ltk40000gn/T/datalad_temp_tree_test_get_recurse_dirsfciy781u
+bash-3.2$ git annex whereis subdir/file2.txt 
+whereis subdir/file2.txt (1 copy) 
+        52043a4d-fab3-4661-a8aa-904cd780c804 -- appveyor@worker-628-003.shared:/private/var/folders/5s/g225f6nd6jl4g8tshbh1ltk40000gn/T/datalad_temp_tree_test_get_recurse_dirsfciy781u [origin]
+ok
+bash-3.2$ git annex get subdir/file2.txt
+get subdir/file2.txt (from origin...) 
+  ../../../../../../../var/folders/5s/g225f6nd6jl4g8tshbh1ltk40000gn/T/datalad_temp_tree_test_get_recurse_dirsfciy781u/.git/annex: createDirectory: does not exist (No such file or directory)
+
+  Unable to access these remotes: origin
+
+  Try making some of these remotes available:
+        52043a4d-fab3-4661-a8aa-904cd780c804 -- appveyor@worker-628-003.shared:/private/var/folders/5s/g225f6nd6jl4g8tshbh1ltk40000gn/T/datalad_temp_tree_test_get_recurse_dirsfciy781u [origin]
+failed
+git-annex: get: 1 failed
+bash-3.2$ ls -l ../../../g225f6nd6jl4g8tshbh1ltk40000gn/T/datalad_temp_test_get_recurse_dirs7eiohcer/.git/annex/
+total 32
+-rw-r--r--  1 appveyor  staff  681 Feb  8 08:09 index
+-rw-r--r--  1 appveyor  staff   41 Feb  8 08:09 index.lck
+drwxr-xr-x  2 appveyor  staff   64 Feb  8 08:09 journal
+-rw-r--r--  1 appveyor  staff    0 Feb  8 08:09 journal.lck
+-rw-r--r--  1 appveyor  staff   71 Feb  8 08:09 mergedrefs
+-rw-r--r--  1 appveyor  staff    0 Feb  8 08:37 move.lck
+-rw-r--r--  1 appveyor  staff    0 Feb  8 08:37 move.log
+-rw-r--r--  1 appveyor  staff    0 Feb  8 08:09 othertmp.lck
+-rw-r--r--  1 appveyor  staff    0 Feb  8 08:09 sentinal
+-rw-r--r--  1 appveyor  staff   34 Feb  8 08:09 sentinal.cache
+-rw-r--r--  1 appveyor  staff    0 Feb  8 08:09 smudge.lck
+drwxr-xr-x  2 appveyor  staff   64 Feb  8 08:09 tmp
+drwxr-xr-x  4 appveyor  staff  128 Feb  8 08:09 transfer
+```
+
+and if it didn't escape all the way to the `/`, mkdir would have even worked:
+```
+bash-3.2$ mkdir ../../../g225f6nd6jl4g8tshbh1ltk40000gn/T/datalad_temp_test_get_recurse_dirs7eiohcer/.git/annex/123
+bash-3.2$ 
+```
+```
+"""]]

update
diff --git a/doc/thanks/list b/doc/thanks/list
index d98b46001..be687f792 100644
--- a/doc/thanks/list
+++ b/doc/thanks/list
@@ -110,3 +110,4 @@ Martin Heistermann,
 Kevin Mueller, 
 Jarkko Kniivilä, 
 Alex, 
+Dr. Land Raider, 

diff --git a/doc/bugs/__91__Patch__93___fix___34__mdwn2man__58___cannot_execute_-_...__34__.mdwn b/doc/bugs/__91__Patch__93___fix___34__mdwn2man__58___cannot_execute_-_...__34__.mdwn
new file mode 100644
index 000000000..4a5a7bed6
--- /dev/null
+++ b/doc/bugs/__91__Patch__93___fix___34__mdwn2man__58___cannot_execute_-_...__34__.mdwn
@@ -0,0 +1,38 @@
+### Please describe the problem.
+
+`cabal v2-install` produces many lines like this in the build log:
+
+    /bin/sh: ./Build/mdwn2man: cannot execute - Permission denied
+
+and the man pages don't get copied to `~/.cabal/store/...`.
+
+My guess is that Cabal is losing the file mode during some tarring/untarring.
+
+Here's a patch that fixes it. (It makes the `#/usr/bin/env perl` at the start of the file redundant; not sure if you want to delete it.)
+
+```
+diff --git a/Build/Mans.hs b/Build/Mans.hs
+index 9fb29d4a3..672dcd71c 100644
+--- a/Build/Mans.hs
++++ b/Build/Mans.hs
+@@ -38,7 +38,8 @@ buildMans = do
+ 		if (Just srcm > destm)
+ 			then do
+ 				r <- system $ unwords
+-					[ "./Build/mdwn2man"
++					[ "perl"
++                                        , "Build/mdwn2man"
+ 					, progName src
+ 					, "1"
+ 					, src
+```
+
+(Related question: is the installation supposed to put the man pages anywhere other than `~/.cabal/store/ghc-XXX/git-annex-XXX`? I.e. is it up to the user to either add that directory to `MANPATH` or copy them somewhere from there?)
+
+### What version of git-annex are you using? On what operating system?
+
+OpenBSD current
+
+Cabal 3.4.0.0
+
+git-annex master (commit `4e5a27841`)