From 082e1f173880d1cbd71b37f47d89152b33dbfb7b Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Tue, 4 Jun 2019 15:14:20 -0400 Subject: [PATCH] Don't try to import .git directories from special remotes Because git does not support storing git repositories inside a git repository. --- Annex/Import.hs | 21 +++++++++++++++++++++ CHANGELOG | 2 ++ Command/Import.hs | 2 +- doc/bugs/import_tree_should_skip_.git.mdwn | 8 ++++++++ 4 files changed, 32 insertions(+), 1 deletion(-) diff --git a/Annex/Import.hs b/Annex/Import.hs index 585deefa24..d70942acd4 100644 --- a/Annex/Import.hs +++ b/Annex/Import.hs @@ -16,6 +16,7 @@ module Annex.Import ( downloadImport, filterImportableContents, makeImportMatcher, + listImportableContents, ) where import Annex.Common @@ -54,6 +55,7 @@ import qualified Logs.ContentIdentifier as CIDLog import Control.Concurrent.STM import qualified Data.Map.Strict as M import qualified Data.Set as S +import qualified System.FilePath.Posix as Posix {- Configures how to build an import tree. -} data ImportTreeConfig @@ -480,3 +482,22 @@ filterImportableContents r matcher importable <*> mapM (go dbhandle) (importableHistory ic) match dbhandle (loc, (_cid, sz)) = shouldImport dbhandle matcher loc sz + +{- Gets the ImportableContents from the remote. + - + - Filters out any paths that include a ".git" component, because git does + - not allow storing ".git" in a git repository. While it is possible to + - write a git tree that contains that, git will complain and refuse to + - check it out. + -} +listImportableContents :: Remote -> Annex (Maybe (ImportableContents (ContentIdentifier, ByteSize))) +listImportableContents r = fmap removegitspecial + <$> Remote.listImportableContents (Remote.importActions r) + where + removegitspecial ic = ImportableContents + { importableContents = + filter (not . gitspecial . fst) (importableContents ic) + , importableHistory = + map removegitspecial (importableHistory ic) + } + gitspecial l = ".git" `elem` Posix.splitDirectories (fromImportLocation l) diff --git a/CHANGELOG b/CHANGELOG index 0cd1e0fab4..1b82d5160a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -11,6 +11,8 @@ git-annex (7.20190508) UNRELEASED; urgency=medium unwanted files are not imported. But, some preferred content expressions can't be checked before files are imported, and trying to import with such an expression will fail. + * Don't try to import .git directories from special remotes, because + git does not support storing git repositories inside a git repository. * Improve shape of commit tree when importing from unversioned special remotes. * init: When the repository already has a description, don't change it. diff --git a/Command/Import.hs b/Command/Import.hs index f890f982bd..c8659a1e92 100644 --- a/Command/Import.hs +++ b/Command/Import.hs @@ -291,7 +291,7 @@ seekRemote remote branch msubdir = do listContents :: Remote -> TVar (Maybe (ImportableContents (ContentIdentifier, Remote.ByteSize))) -> CommandStart listContents remote tvar = do showStart' "list" (Just (Remote.name remote)) - next $ Remote.listImportableContents (Remote.importActions remote) >>= \case + next $ listImportableContents remote >>= \case Nothing -> giveup $ "Unable to list contents of " ++ Remote.name remote Just importable -> do importable' <- makeImportMatcher remote >>= \case diff --git a/doc/bugs/import_tree_should_skip_.git.mdwn b/doc/bugs/import_tree_should_skip_.git.mdwn index 589e52eb3d..8ef9df8ee9 100644 --- a/doc/bugs/import_tree_should_skip_.git.mdwn +++ b/doc/bugs/import_tree_should_skip_.git.mdwn @@ -19,6 +19,14 @@ The solution is certianly to 1. filter out .git when importing 2. avoid deleting .git when exporting + As long as the export tracking branch did not contain .git, + an export will harm no .git directories, because an exporttree + remote uses removeExportDirectoryWhenEmpty, not removeExportDirectory, + so will not delete non-empty directories. And other than deleting + directories, exporting only deletes files that are removed in the git + diff between two trees; if neither tree contained .git, the diff won't + contain it either, and so if importing skips .git, this will be ok. + --[[Joey]] > [[fixed|done]] --[[Joey]]