annex.maxextensionlength for view

view: Support annex.maxextensionlength when generating filenames for the
view branch.

Note that refining an existing view will reuse the extension length that was
configured when initially constructing the view. This is necessarily the case
because it reuses the filenames.

Also view files used to have all extensions at the end, no matter how
many there were. Since annex.maxextensionlength's documentation includes
that it's limited to 2 extensions, I made it consistent with that.

Sponsored-by: k0ld on Patreon
This commit is contained in:
Joey Hess 2023-03-24 13:53:51 -04:00
parent 70a9e995b8
commit 2b5fa091e2
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
7 changed files with 48 additions and 14 deletions

View file

@ -387,7 +387,7 @@ prop_view_roundtrips (AssociatedFile Nothing) _ _ = True
prop_view_roundtrips (AssociatedFile (Just f)) metadata visible = or
[ B.null (P.takeFileName f) && B.null (P.takeDirectory f)
, viewTooLarge view
, all hasfields (viewedFiles view viewedFileFromReference (fromRawFilePath f) metadata)
, all hasfields (viewedFiles view (viewedFileFromReference' Nothing) (fromRawFilePath f) metadata)
]
where
view = View (Git.Ref "foo") $
@ -421,7 +421,9 @@ getViewedFileMetaData = getDirMetaData . dirFromViewedFile . takeFileName
- branch for the view.
-}
applyView :: View -> Maybe Adjustment -> Annex Git.Branch
applyView = applyView' viewedFileFromReference getWorkTreeMetaData
applyView v ma = do
gc <- Annex.getGitConfig
applyView' (viewedFileFromReference gc) getWorkTreeMetaData v ma
{- Generates a new branch for a View, which must be a more narrow
- version of the View originally used to generate the currently
@ -553,7 +555,8 @@ updateView view madj = do
Git.LsTree.LsTreeRecursive
(Git.LsTree.LsTreeLong True)
(viewParentBranch view)
applyView'' viewedFileFromReference getWorkTreeMetaData view madj l clean $
gc <- Annex.getGitConfig
applyView'' (viewedFileFromReference gc) getWorkTreeMetaData view madj l clean $
\ti -> do
let ref = Git.Ref.branchFileRef (viewParentBranch view)
(getTopFilePath (Git.LsTree.file ti))

View file

@ -1,6 +1,6 @@
{- filenames (not paths) used in views
-
- Copyright 2014 Joey Hess <id@joeyh.name>
- Copyright 2014-2023 Joey Hess <id@joeyh.name>
-
- Licensed under the GNU AGPL version 3 or higher.
-}
@ -11,6 +11,7 @@ module Annex.View.ViewedFile (
ViewedFile,
MkViewedFile,
viewedFileFromReference,
viewedFileFromReference',
viewedFileReuse,
dirFromViewedFile,
prop_viewedFile_roundtrips,
@ -35,17 +36,27 @@ type MkViewedFile = FilePath -> ViewedFile
-
- So, from dir/subdir/file.foo, generate file_%dir%subdir%.foo
-}
viewedFileFromReference :: MkViewedFile
viewedFileFromReference f = concat $
[ escape (fromRawFilePath base)
viewedFileFromReference :: GitConfig -> MkViewedFile
viewedFileFromReference g = viewedFileFromReference' (annexMaxExtensionLength g)
viewedFileFromReference' :: Maybe Int -> MkViewedFile
viewedFileFromReference' maxextlen f = concat $
[ escape (fromRawFilePath base')
, if null dirs then "" else "_%" ++ intercalate "%" (map escape dirs) ++ "%"
, escape $ fromRawFilePath $ S.concat extensions
, escape $ fromRawFilePath $ S.concat extensions'
]
where
(path, basefile) = splitFileName f
dirs = filter (/= ".") $ map dropTrailingPathSeparator (splitPath path)
(base, extensions) = splitShortExtensions (toRawFilePath basefile')
(base, extensions) = case maxextlen of
Nothing -> splitShortExtensions (toRawFilePath basefile')
Just n -> splitShortExtensions' (n+1) (toRawFilePath basefile')
{- Limit to two extensions maximum. -}
(base', extensions')
| length extensions <= 2 = (base, extensions)
| otherwise =
let (es,more) = splitAt 2 (reverse extensions)
in (base <> mconcat (reverse more), reverse es)
{- On Windows, if the filename looked like "dir/c:foo" then
- basefile would look like it contains a drive letter, which will
- not work. There cannot really be a filename like that, probably,
@ -90,7 +101,7 @@ prop_viewedFile_roundtrips tf
-- Relative filenames wanted, not directories.
| any (isPathSeparator) (end f ++ beginning f) = True
| isAbsolute f || isDrive f = True
| otherwise = dir == dirFromViewedFile (viewedFileFromReference f)
| otherwise = dir == dirFromViewedFile (viewedFileFromReference' Nothing f)
where
f = fromTestableFilePath tf
dir = joinPath $ beginning $ splitDirectories f

View file

@ -5,6 +5,8 @@ git-annex (10.20230322) UNRELEASED; urgency=medium
drop when annex.adjustedbranchrefresh=1
* Avoid leaving repo with a detached head when there is a failure
checking out an updated adjusted branch.
* view: Support annex.maxextensionlength when generating filenames for
the view branch.
-- Joey Hess <id@joeyh.name> Thu, 23 Mar 2023 15:04:41 -0400

View file

@ -20,6 +20,7 @@ module Utility.Path (
runSegmentPaths',
dotfile,
splitShortExtensions,
splitShortExtensions',
relPathDirToFileAbs,
inSearchPath,
searchPath,

View file

@ -44,6 +44,12 @@ into the `_` directory and committing will unset the metadata.
The name of the `_` directory can be changed using the annex.viewunsetdirectory
git config.
Filenames in the view branch include their path within the original branch, to
ensure that they are unique. The path comes after the main filename, and
before any extensions. For example, "foo/bar.baz" will have a name
like "bar_%foo%.baz". annex.maxextensionlength can be used to configure
what is treated as an extension.
# OPTIONS
* The [[git-annex-common-options]](1) can be used.

View file

@ -825,9 +825,11 @@ repository, using [[git-annex-config]]. See its man page for a list.)
* `annex.maxextensionlength`
Maximum length, in bytes, of what is considered a filename extension when
adding a file to a backend that preserves filename extensions. The
default length is 4, which allows extensions like "jpeg". The dot before
Maximum length, in bytes, of what is considered a filename extension.
This is used when adding a file to a backend that preserves filename extensions,
and also when generating a view branch.
The default length is 4, which allows extensions like "jpeg". The dot before
the extension is not counted part of its length. At most two extensions
at the end of a filename will be preserved, e.g. .gz or .tar.gz .

View file

@ -0,0 +1,9 @@
[[!comment format=mdwn
username="joey"
subject="""comment 8"""
date="2023-03-24T17:48:43Z"
content="""
I've made git-annex view use `annex.maxextensionlength`. Note that refining
an existing view will reuse the extension length that was configured when
initially constructing the view.
"""]]