From 46fe686ba0972f91e0906e1024831d6c69f9fc17 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Mon, 15 Feb 2016 11:13:26 -0400 Subject: [PATCH 01/58] remove Utility.Mounts et al; moved to mountpoints package --- Utility/Mounts.hs | 21 +++++++++ Utility/Mounts.hsc | 97 ----------------------------------------- Utility/libmounts.c | 103 -------------------------------------------- Utility/libmounts.h | 38 ---------------- debian/copyright | 45 ------------------- git-annex.cabal | 5 +-- 6 files changed, 23 insertions(+), 286 deletions(-) create mode 100644 Utility/Mounts.hs delete mode 100644 Utility/Mounts.hsc delete mode 100644 Utility/libmounts.c delete mode 100644 Utility/libmounts.h diff --git a/Utility/Mounts.hs b/Utility/Mounts.hs new file mode 100644 index 0000000000..192da31a1c --- /dev/null +++ b/Utility/Mounts.hs @@ -0,0 +1,21 @@ +{- portability shim for System.MountPoints + - + - Copyright 2016 Joey Hess + - + - License: BSD-2-clause + -} + +{-# LANGUAGE CPP #-} +{-# OPTIONS_GHC -fno-warn-tabs #-} + +module Utility.Mounts (getMounts, Mntent(..)) where + +import qualified System.MountPoints +import System.MountPoints (Mntent(..)) + +getMounts :: IO [Mntent] +#ifndef __ANDROID__ +getMounts = System.MountPoints.getMounts +#else +getMounts = System.MountPoints.getProcMounts +#endif diff --git a/Utility/Mounts.hsc b/Utility/Mounts.hsc deleted file mode 100644 index 3f121233ab..0000000000 --- a/Utility/Mounts.hsc +++ /dev/null @@ -1,97 +0,0 @@ -{- Interface to mtab (and fstab) - - - - Deprecated; moving to mountpoints library on hackage. - - - - Derived from hsshellscript, originally written by - - Volker Wysk - - - - Modified to support BSD, Mac OS X, and Android by - - Joey Hess - - - - Licensed under the GNU LGPL version 2.1 or higher. - - - -} - -{-# LANGUAGE ForeignFunctionInterface #-} - -module Utility.Mounts ( - Mntent(..), - getMounts -) where - -#ifndef __ANDROID__ -import Control.Monad -import Foreign -import Foreign.C -#include "libmounts.h" -#else -import Utility.Exception -import Data.Maybe -import Control.Applicative -#endif -import Prelude - -{- This is a stripped down mntent, containing only - - fields available everywhere. -} -data Mntent = Mntent - { mnt_fsname :: String - , mnt_dir :: FilePath - , mnt_type :: String - } deriving (Show, Eq, Ord) - -#ifndef __ANDROID__ - -getMounts :: IO [Mntent] -getMounts = do - h <- c_mounts_start - when (h == nullPtr) $ - throwErrno "getMounts" - mntent <- getmntent h [] - _ <- c_mounts_end h - return mntent - - where - getmntent h c = do - ptr <- c_mounts_next h - if (ptr == nullPtr) - then return $ reverse c - else do - mnt_fsname_str <- #{peek struct mntent, mnt_fsname} ptr >>= peekCString - mnt_dir_str <- #{peek struct mntent, mnt_dir} ptr >>= peekCString - mnt_type_str <- #{peek struct mntent, mnt_type} ptr >>= peekCString - let ent = Mntent - { mnt_fsname = mnt_fsname_str - , mnt_dir = mnt_dir_str - , mnt_type = mnt_type_str - } - getmntent h (ent:c) - -{- Using unsafe imports because the C functions are belived to never block. - - Note that getmntinfo is called with MNT_NOWAIT to avoid possibly blocking; - - while getmntent only accesses a file in /etc (or /proc) that should not - - block. -} -foreign import ccall unsafe "libmounts.h mounts_start" c_mounts_start - :: IO (Ptr ()) -foreign import ccall unsafe "libmounts.h mounts_next" c_mounts_next - :: Ptr () -> IO (Ptr ()) -foreign import ccall unsafe "libmounts.h mounts_end" c_mounts_end - :: Ptr () -> IO CInt - -#else - -{- Android does not support getmntent (well, it's a no-op stub in Bionic). - - - - But, the linux kernel's /proc/mounts is available to be parsed. - -} -getMounts :: IO [Mntent] -getMounts = catchDefaultIO [] $ - mapMaybe (parse . words) . lines <$> readFile "/proc/mounts" - where - parse (device:mountpoint:fstype:_rest) = Just $ Mntent - { mnt_fsname = device - , mnt_dir = mountpoint - , mnt_type = fstype - } - parse _ = Nothing - -#endif diff --git a/Utility/libmounts.c b/Utility/libmounts.c deleted file mode 100644 index c469d77103..0000000000 --- a/Utility/libmounts.c +++ /dev/null @@ -1,103 +0,0 @@ -/* mounted filesystems, C mini-library - * - * Copyright (c) 1980, 1989, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * Copyright (c) 2001 - * David Rufino - * Copyright 2012 - * Joey Hess - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "libmounts.h" - -#ifdef GETMNTENT -/* direct passthrough the getmntent */ -FILE *mounts_start (void) { - return setmntent("/etc/mtab", "r"); -} -int mounts_end (FILE *fp) { - return endmntent(fp); -} -struct mntent *mounts_next (FILE *fp) { - return getmntent(fp); -} -#endif - -#ifdef GETMNTINFO -/* getmntent emulation using getmntinfo */ -FILE *mounts_start (void) { - return ((FILE *)0x1); /* dummy non-NULL FILE pointer, not used */ -} -int mounts_end (FILE *fp) { - return 1; -} - -static struct mntent _mntent; - -static struct mntent *statfs_to_mntent (struct statfs *mntbuf) { - _mntent.mnt_fsname = mntbuf->f_mntfromname; - _mntent.mnt_dir = mntbuf->f_mntonname; - _mntent.mnt_type = mntbuf->f_fstypename; - - _mntent.mnt_opts = NULL; - _mntent.mnt_freq = 0; - _mntent.mnt_passno = 0; - - return (&_mntent); -} - -static int pos = -1; -static int mntsize = -1; -struct statfs *mntbuf = NULL; - -struct mntent *mounts_next (FILE *fp) { - - if (pos == -1 || mntsize == -1) - mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); - ++pos; - if (pos == mntsize) { - pos = mntsize = -1; - mntbuf = NULL; - return NULL; - } - - return (statfs_to_mntent(&mntbuf[pos])); -} -#endif - -#ifdef UNKNOWN -/* dummy, do-nothing version */ -FILE *mounts_start (void) { - return ((FILE *)0x1); -} -int mounts_end (FILE *fp) { - return 1; -} -struct mntent *mounts_next (FILE *fp) { - return NULL; -} -#endif diff --git a/Utility/libmounts.h b/Utility/libmounts.h deleted file mode 100644 index 24df55f310..0000000000 --- a/Utility/libmounts.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Include appropriate headers for the OS, and define what will be used. */ -#if defined (__FreeBSD__) || defined (__APPLE__) -# include -# include -# include -# define GETMNTINFO -#else -#if defined __ANDROID__ -/* Android is handled by the Haskell code, not here. */ -# define UNKNOWN -#else -#if defined (__linux__) || defined (__FreeBSD_kernel__) -/* Linux or Debian kFreeBSD */ -#include -# define GETMNTENT -#else -# warning mounts listing code not available for this OS -# define UNKNOWN -#endif -#endif -#endif - -#include - -#ifndef GETMNTENT -struct mntent { - char *mnt_fsname; - char *mnt_dir; - char *mnt_type; - char *mnt_opts; /* not filled in */ - int mnt_freq; /* not filled in */ - int mnt_passno; /* not filled in */ -}; -#endif - -FILE *mounts_start (void); -int mounts_end (FILE *fp); -struct mntent *mounts_next (FILE *fp); diff --git a/debian/copyright b/debian/copyright index 5f80d40507..4f89d811bc 100644 --- a/debian/copyright +++ b/debian/copyright @@ -35,51 +35,11 @@ Copyright: 2007 Henrik Nyh License: other Free to modify and redistribute with due credit, and obviously free to use. -Files: Utility/Mounts.hsc -Copyright: Volker Wysk -License: LGPL-2.1+ - Files: Annex/DirHashes.hs Copyright: 2001 Ian Lynagh 2010-2015 Joey Hess License: GPL-3+ -Files: Utility/libmounts.c -Copyright: 1980, 1989, 1993, 1994 The Regents of the University of California - 2001 David Rufino - 2012 Joey Hess -License: BSD-3-clause - * Copyright (c) 1980, 1989, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * Copyright (c) 2001 - * David Rufino - * Copyright 2012 - * Joey Hess - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - Files: static/jquery* Copyright: © 2005-2011 by John Resig, Branden Aaron & Jörn Zaefferer © 2011 The Dojo Foundation @@ -135,11 +95,6 @@ License: GPL-3+ this package's source, or in /usr/share/common-licenses/GPL-3 on Debian systems. -License: LGPL-2.1+ - The full text of version 2.1 of the LGPL is distributed as doc/license/LGPL - in this package's source, or in /usr/share/common-licenses/LGPL-2.1 - on Debian systems. - License: BSD-2-clause Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/git-annex.cabal b/git-annex.cabal index fa496d8e01..4edbd21c3b 100644 --- a/git-annex.cabal +++ b/git-annex.cabal @@ -144,9 +144,8 @@ Executable git-annex else Build-Depends: unix -- Need to list these because they're generated from .hsc files. - Other-Modules: Utility.Touch Utility.Mounts + Other-Modules: Utility.Touch Include-Dirs: Utility - C-Sources: Utility/libdiskfree.c Utility/libmounts.c CPP-Options: -DWITH_CLIBS if flag(TestSuite) @@ -163,7 +162,7 @@ Executable git-annex CPP-Options: -DWITH_WEBDAV if flag(Assistant) && ! os(solaris) - Build-Depends: dns + Build-Depends: dns, mountpoints CPP-Options: -DWITH_ASSISTANT if flag(Assistant) From a665f92b91cf970e5af01cca94b1971df80bec2d Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Mon, 15 Feb 2016 11:29:27 -0400 Subject: [PATCH 02/58] switch from homegrown code to disk-free-space According to https://github.com/redneb/disk-free-space/issues/3 , disk-free-space should be at least as portable as my homegrown code was. One change I noticed is, getDiskSize was not implemented for windows in the old code, and should work now. --- Utility/DiskFree.hs | 63 +++++--------------------------- Utility/libdiskfree.c | 84 ------------------------------------------- Utility/libdiskfree.h | 1 - git-annex.cabal | 3 +- 4 files changed, 10 insertions(+), 141 deletions(-) delete mode 100644 Utility/libdiskfree.c delete mode 100644 Utility/libdiskfree.h diff --git a/Utility/DiskFree.hs b/Utility/DiskFree.hs index c4125d4f00..fe3a4577c1 100644 --- a/Utility/DiskFree.hs +++ b/Utility/DiskFree.hs @@ -1,70 +1,23 @@ -{- disk free space checking +{- disk free space checking shim - - - Copyright 2012, 2014 Joey Hess + - Copyright 2016 Joey Hess - - License: BSD-2-clause -} -{-# LANGUAGE ForeignFunctionInterface, CPP #-} +{-# OPTIONS_GHC -fno-warn-tabs #-} module Utility.DiskFree ( getDiskFree, getDiskSize ) where -#ifdef WITH_CLIBS - -import Common - -import Foreign.C.Types -import Foreign.C.String -import Foreign.C.Error - -foreign import ccall safe "libdiskfree.h diskfree" c_diskfree - :: CString -> IO CULLong - -foreign import ccall safe "libdiskfree.h disksize" c_disksize - :: CString -> IO CULLong - -getVal :: (CString -> IO CULLong) -> FilePath -> IO (Maybe Integer) -getVal getter path = withFilePath path $ \c_path -> do - free <- getter c_path - ifM (safeErrno <$> getErrno) - ( return $ Just $ toInteger free - , return Nothing - ) - where - safeErrno (Errno v) = v == 0 +import System.DiskSpace +import Utility.Applicative +import Utility.Exception getDiskFree :: FilePath -> IO (Maybe Integer) -getDiskFree = getVal c_diskfree +getDiskFree = catchMaybeIO . getAvailSpace getDiskSize :: FilePath -> IO (Maybe Integer) -getDiskSize = getVal c_disksize - -#else -#ifdef mingw32_HOST_OS - -import Common - -import System.Win32.File - -getDiskFree :: FilePath -> IO (Maybe Integer) -getDiskFree path = catchMaybeIO $ do - (sectors, bytes, nfree, _ntotal) <- getDiskFreeSpace (Just path) - return $ toInteger sectors * toInteger bytes * toInteger nfree - -getDiskSize :: FilePath -> IO (Maybe Integer) -getDiskSize _ = return Nothing -#else - -#warning Building without disk free space checking support - -getDiskFree :: FilePath -> IO (Maybe Integer) -getDiskFree _ = return Nothing - -getDiskSize :: FilePath -> IO (Maybe Integer) -getDiskSize _ = return Nothing - -#endif -#endif +getDiskSize = fmap diskTotal <$$> catchMaybeIO . getDiskUsage diff --git a/Utility/libdiskfree.c b/Utility/libdiskfree.c deleted file mode 100644 index a682bb3bd3..0000000000 --- a/Utility/libdiskfree.c +++ /dev/null @@ -1,84 +0,0 @@ -/* disk free space checking, C mini-library - * - * Copyright 2012, 2014 Joey Hess - * - * License: BSD-2-clause - */ - -/* Include appropriate headers for the OS, and define what will be used to - * check the free space. */ -#if defined (__FreeBSD__) -# include -# include -# define STATCALL statfs /* statfs64 not yet tested on a real FreeBSD machine */ -# define STATSTRUCT statfs -# define BSIZE f_bsize -#else -#if defined __ANDROID__ -# warning free space checking code not available for Android -# define UNKNOWN -#else -#if defined (__linux__) || defined (__APPLE__) || defined (__FreeBSD_kernel__) || (defined (__SVR4) && defined (__sun)) -/* Linux or OSX or Debian kFreeBSD or Solaris */ -/* This is a POSIX standard, so might also work elsewhere too. */ -# include -# define STATCALL statvfs -# define STATSTRUCT statvfs -# define BSIZE f_frsize -#else -# warning free space checking code not available for this OS -# define UNKNOWN -#endif -#endif -#endif - -#include -#include - -unsigned long long int get(const char *path, int req) { -#ifdef UNKNOWN - errno = 1; - return 0; -#else - unsigned long long int v, blocksize; - struct STATSTRUCT buf; - - if (STATCALL(path, &buf) != 0) - return 0; /* errno is set */ - else - errno = 0; - - switch (req) { - case 0: - v = buf.f_blocks; - break; - case 1: - v = buf.f_bavail; - break; - default: - v = 0; - } - - blocksize = buf.BSIZE; - return v * blocksize; -#endif -} - -/* Checks the amount of disk that is available to regular (non-root) users. - * (If there's an error, or this is not supported, - * returns 0 and sets errno to nonzero.) - */ -unsigned long long int diskfree(const char *path) { - return get(path, 1); -} - -/* Gets the total size of the disk. */ -unsigned long long int disksize(const char *path) { - return get(path, 0); -} - -/* -main () { - printf("%lli\n", diskfree(".")); -} -*/ diff --git a/Utility/libdiskfree.h b/Utility/libdiskfree.h deleted file mode 100644 index e5b84754fe..0000000000 --- a/Utility/libdiskfree.h +++ /dev/null @@ -1 +0,0 @@ -unsigned long long int diskfree(const char *path); diff --git a/git-annex.cabal b/git-annex.cabal index 4edbd21c3b..8e6efbf592 100644 --- a/git-annex.cabal +++ b/git-annex.cabal @@ -111,7 +111,8 @@ Executable git-annex esqueleto, persistent-sqlite, persistent, persistent-template, aeson, feed, - regex-tdfa + regex-tdfa, + disk-free-space CC-Options: -Wall GHC-Options: -Wall -fno-warn-tabs Extensions: PackageImports From 40207b26ea81fbb50c455de3a4e0c1046ede8c23 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Mon, 15 Feb 2016 11:47:33 -0400 Subject: [PATCH 03/58] move old ghc compat code into separate module; eliminate WITH_CLIBS This avoids hsc2hs being run except when building for the old version of ghc. Should speed up builds. --- Annex/Ingest.hs | 12 +----- Assistant.hs | 4 +- Assistant/WebApp/Configurators/Local.hs | 6 --- Command/Fix.hs | 12 +----- Utility/Touch.hs | 52 +++++++++++++++++++++++++ Utility/{Touch.hsc => Touch/Old.hsc} | 26 +------------ git-annex.cabal | 6 +-- 7 files changed, 61 insertions(+), 57 deletions(-) create mode 100644 Utility/Touch.hs rename Utility/{Touch.hsc => Touch/Old.hsc} (82%) diff --git a/Annex/Ingest.hs b/Annex/Ingest.hs index 0dd8b5967a..68db3eef08 100644 --- a/Annex/Ingest.hs +++ b/Annex/Ingest.hs @@ -5,8 +5,6 @@ - Licensed under the GNU GPL version 3 or higher. -} -{-# LANGUAGE CPP #-} - module Annex.Ingest ( LockedDown(..), LockDownConfig(..), @@ -38,13 +36,9 @@ import Utility.InodeCache import Annex.ReplaceFile import Utility.Tmp import Utility.CopyFile +import Utility.Touch import Git.FilePath import Annex.InodeSentinal -#ifdef WITH_CLIBS -#ifndef __ANDROID__ -import Utility.Touch -#endif -#endif import Control.Exception (IOException) @@ -260,11 +254,7 @@ makeLink file key mcache = flip catchNonAsync (restoreFile file key) $ do -- touch symlink to have same time as the original file, -- as provided in the InodeCache case mcache of -#if defined(WITH_CLIBS) && ! defined(__ANDROID__) Just c -> liftIO $ touch file (TimeSpec $ inodeCacheToMtime c) False -#else - Just _ -> noop -#endif Nothing -> noop return l diff --git a/Assistant.hs b/Assistant.hs index 265827a773..4dab6f162c 100644 --- a/Assistant.hs +++ b/Assistant.hs @@ -25,7 +25,7 @@ import Assistant.Threads.RemoteControl import Assistant.Threads.SanityChecker import Assistant.Threads.Cronner import Assistant.Threads.ProblemFixer -#ifdef WITH_CLIBS +#ifndef mingw32_HOST_OS import Assistant.Threads.MountWatcher #endif import Assistant.Threads.NetWatcher @@ -170,7 +170,7 @@ startDaemon assistant foreground startdelay cannotrun listenhost startbrowser = , assist $ sanityCheckerDailyThread urlrenderer , assist sanityCheckerHourlyThread , assist $ problemFixerThread urlrenderer -#ifdef WITH_CLIBS +#ifndef mingw32_HOST_OS , assist $ mountWatcherThread urlrenderer #endif , assist netWatcherThread diff --git a/Assistant/WebApp/Configurators/Local.hs b/Assistant/WebApp/Configurators/Local.hs index a2a465b875..b3f5f6e782 100644 --- a/Assistant/WebApp/Configurators/Local.hs +++ b/Assistant/WebApp/Configurators/Local.hs @@ -24,9 +24,7 @@ import qualified Git.Branch import Config.Files import Utility.FreeDesktop import Utility.DiskFree -#ifdef WITH_CLIBS import Utility.Mounts -#endif import Utility.DataUnits import Remote (prettyUUID) import Annex.UUID @@ -359,7 +357,6 @@ driveList :: IO [RemovableDrive] -- Could use wmic, but it only works for administrators. driveList = mapM (\d -> genRemovableDrive $ d:":\\") ['A'..'Z'] #else -#ifdef WITH_CLIBS driveList = mapM (genRemovableDrive . mnt_dir) =<< filter sane <$> getMounts where -- filter out some things that are surely not removable drives @@ -379,9 +376,6 @@ driveList = mapM (genRemovableDrive . mnt_dir) =<< filter sane <$> getMounts | dir == "/sdcard" = False #endif | otherwise = True -#else -driveList = return [] -#endif #endif genRemovableDrive :: FilePath -> IO RemovableDrive diff --git a/Command/Fix.hs b/Command/Fix.hs index 5565a68372..d87bea3585 100644 --- a/Command/Fix.hs +++ b/Command/Fix.hs @@ -18,11 +18,7 @@ import Annex.Content import Annex.Perms import qualified Annex.Queue import qualified Database.Keys -#ifdef WITH_CLIBS -#ifndef __ANDROID__ import Utility.Touch -#endif -#endif cmd :: Command cmd = notDirect $ noCommit $ withGlobalOptions annexedMatchingOptions $ @@ -90,20 +86,16 @@ makeHardLink file key = do fixSymlink :: FilePath -> FilePath -> CommandPerform fixSymlink file link = do liftIO $ do -#ifdef WITH_CLIBS -#ifndef __ANDROID__ +#if ! defined(mingw32_HOST_OS) && ! defined(__ANDROID__) -- preserve mtime of symlink mtime <- catchMaybeIO $ TimeSpec . modificationTime <$> getSymbolicLinkStatus file -#endif #endif createDirectoryIfMissing True (parentDir file) removeFile file createSymbolicLink link file -#ifdef WITH_CLIBS -#ifndef __ANDROID__ +#if ! defined(mingw32_HOST_OS) && ! defined(__ANDROID__) maybe noop (\t -> touch file t False) mtime -#endif #endif next $ cleanupSymlink file diff --git a/Utility/Touch.hs b/Utility/Touch.hs new file mode 100644 index 0000000000..60b9cb928c --- /dev/null +++ b/Utility/Touch.hs @@ -0,0 +1,52 @@ +{- More control over touching a file. + - + - Copyright 2011 Joey Hess + - + - License: BSD-2-clause + -} + +{-# LANGUAGE CPP #-} + +module Utility.Touch ( + TimeSpec(..), + touchBoth, + touch +) where + +#if ! defined(mingw32_HOST_OS) && ! defined(__ANDROID__) + +#if MIN_VERSION_unix(2,7,0) + +import System.Posix.Files +import System.Posix.Types + +newtype TimeSpec = TimeSpec EpochTime + +{- Changes the access and modification times of an existing file. + Can follow symlinks, or not. Throws IO error on failure. -} +touchBoth :: FilePath -> TimeSpec -> TimeSpec -> Bool -> IO () +touchBoth file (TimeSpec atime) (TimeSpec mtime) follow + | follow = setFileTimes file atime mtime + | otherwise = setSymbolicLinkTimesHiRes file (realToFrac atime) (realToFrac mtime) + +touch :: FilePath -> TimeSpec -> Bool -> IO () +touch file mtime = touchBoth file mtime mtime + +#else +import Utility.Touch.Old +#endif + +#else + +import System.PosixCompat + +newtype TimeSpec = TimeSpec EpochTime + +{- Noop for Windows -} +touchBoth FilePath -> TimeSpec -> TimeSpec -> Bool -> IO () +touchBoth _ _ _ _ = return () + +touch :: FilePath -> TimeSpec -> Bool -> IO () +touch _ _ = return () + +#endif diff --git a/Utility/Touch.hsc b/Utility/Touch/Old.hsc similarity index 82% rename from Utility/Touch.hsc rename to Utility/Touch/Old.hsc index e1b1e887e9..5345285f46 100644 --- a/Utility/Touch.hsc +++ b/Utility/Touch/Old.hsc @@ -1,4 +1,4 @@ -{- More control over touching a file. +{- Compatability interface for old version of unix, to be removed eventally. - - Copyright 2011 Joey Hess - @@ -7,32 +7,12 @@ {-# LANGUAGE ForeignFunctionInterface, CPP #-} -module Utility.Touch ( +module Utility.Touch.Old ( TimeSpec(..), touchBoth, touch ) where -#if MIN_VERSION_unix(2,7,0) - -import System.Posix.Files -import System.Posix.Types - -newtype TimeSpec = TimeSpec EpochTime - -{- Changes the access and modification times of an existing file. - Can follow symlinks, or not. Throws IO error on failure. -} -touchBoth :: FilePath -> TimeSpec -> TimeSpec -> Bool -> IO () -touchBoth file (TimeSpec atime) (TimeSpec mtime) follow - | follow = setFileTimes file atime mtime - | otherwise = setSymbolicLinkTimesHiRes file (realToFrac atime) (realToFrac mtime) - -touch :: FilePath -> TimeSpec -> Bool -> IO () -touch file mtime = touchBoth file mtime mtime - -#else -{- Compatability interface for old version of unix, to be removed eventally. -} - #include #include #include @@ -141,5 +121,3 @@ touchBoth file atime mtime follow = touchBoth _ _ _ _ = return () #endif #endif - -#endif diff --git a/git-annex.cabal b/git-annex.cabal index 8e6efbf592..4a1e28f17a 100644 --- a/git-annex.cabal +++ b/git-annex.cabal @@ -144,10 +144,8 @@ Executable git-annex process (>= 1.3.0.0) else Build-Depends: unix - -- Need to list these because they're generated from .hsc files. - Other-Modules: Utility.Touch - Include-Dirs: Utility - CPP-Options: -DWITH_CLIBS + if impl(ghc <= 7.6.3) + Other-Modules: Utility.Touch.Old if flag(TestSuite) Build-Depends: tasty (>= 0.7), tasty-hunit, tasty-quickcheck, tasty-rerun, From b1217e0a5a453c1cfd4cd15d2924792e2dfe273e Mon Sep 17 00:00:00 2001 From: "acbg@8d58f794ce92f6be28b5dbd402059bc30262eb92" Date: Thu, 3 Mar 2016 16:16:28 +0000 Subject: [PATCH 04/58] Added a comment: Since which version does this apply? --- ...comment_1_b84e5cb8316c30fc7b355234384a5899._comment | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 doc/tips/largefiles/comment_1_b84e5cb8316c30fc7b355234384a5899._comment diff --git a/doc/tips/largefiles/comment_1_b84e5cb8316c30fc7b355234384a5899._comment b/doc/tips/largefiles/comment_1_b84e5cb8316c30fc7b355234384a5899._comment new file mode 100644 index 0000000000..79374cd14a --- /dev/null +++ b/doc/tips/largefiles/comment_1_b84e5cb8316c30fc7b355234384a5899._comment @@ -0,0 +1,10 @@ +[[!comment format=mdwn + username="acbg@8d58f794ce92f6be28b5dbd402059bc30262eb92" + nickname="acbg" + subject="Since which version does this apply?" + date="2016-03-03T16:16:28Z" + content=""" +I use version 5.20140412, and I've tried the annex.largefiles in .gitattributes, but doesn't work. Every file is added to .git/annex/objects, including the ones that are excluded in .gitattributes. + +I've just started using git-annex so maybe I'm doing something wrong... +"""]] From 0aec17ea5557faf192e85786e3f324d99e2e3f02 Mon Sep 17 00:00:00 2001 From: Horus Date: Thu, 3 Mar 2016 18:17:35 +0000 Subject: [PATCH 05/58] Added a comment --- ..._6b110311f4c147dc315c4f610cf56afa._comment | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 doc/forum/How_to_shrink_transfer_repo__63__/comment_1_6b110311f4c147dc315c4f610cf56afa._comment diff --git a/doc/forum/How_to_shrink_transfer_repo__63__/comment_1_6b110311f4c147dc315c4f610cf56afa._comment b/doc/forum/How_to_shrink_transfer_repo__63__/comment_1_6b110311f4c147dc315c4f610cf56afa._comment new file mode 100644 index 0000000000..5c1c71475d --- /dev/null +++ b/doc/forum/How_to_shrink_transfer_repo__63__/comment_1_6b110311f4c147dc315c4f610cf56afa._comment @@ -0,0 +1,19 @@ +[[!comment format=mdwn + username="Horus" + subject="comment 1" + date="2016-03-03T18:17:35Z" + content=""" +Ok, I try to do 2) but it still fails: + +``` +dropunused 265 (from astarte...) (unsafe) + Could only verify the existence of 0 out of 1 necessary copies + + Rather than dropping this file, try using: git annex move + + (Use --force to override this check, or adjust numcopies.) +failed +``` + +all repositories are reachable directly. +"""]] From 292414aa4f19a3047688ce3a333837cc2c208854 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Thu, 3 Mar 2016 17:19:11 -0400 Subject: [PATCH 06/58] devblog --- .../day_369-370__paddling_furiously.mdwn | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 doc/devblog/day_369-370__paddling_furiously.mdwn diff --git a/doc/devblog/day_369-370__paddling_furiously.mdwn b/doc/devblog/day_369-370__paddling_furiously.mdwn new file mode 100644 index 0000000000..59dc8dda0a --- /dev/null +++ b/doc/devblog/day_369-370__paddling_furiously.mdwn @@ -0,0 +1,72 @@ +Tuesday was spent dealing with lock files. Turned out there were some bugs +in the `annex.pidlock` configuration that prevented it from working, and +could even lead to data loss. + +And then more lock files today, since I needed to lock git's index file the +same way git does. This involved finding out how to emulate `O_EXCL` under +Windows. Urgh. + +Finally got back to working on [[adjusted_branches]] today. And, I've just +gotten syncing of commits from adjusted branches back to the orginal branch +working! Time for short demo of what I've been building for the past couple +weeks: + + joey@darkstar:~/tmp/demo>ls -l + total 4 + lrwxrwxrwx 1 joey joey 190 Mar 3 17:09 bigfile -> .git/annex/objects/zx/X8/SHA256E-s1048576--44ee9fdd91d4bc567355f8b2becd5fe137b9e3aafdfe804341ce2bcc73b8013f/SHA256E-s1048576--44ee9fdd91d4bc567355f8b2becd5fe137b9e3aafdfe804341ce2bcc73b8013f + joey@darkstar:~/tmp/demo>git annex adjust + Switched to branch 'adjusted/master(unlocked)' + ok + joey@darkstar:~/tmp/demo#master(unlocked)>ls -l + total 4 + -rw-r--r-- 1 joey joey 1048576 Mar 3 17:09 bigfile + +Entering the adjusted branch unlocked all the files. + + joey@darkstar:~/tmp/demo#master(unlocked)>git mv bigfile newname + joey@darkstar:~/tmp/demo#master(unlocked)>git commit -m rename + [adjusted/master(unlocked) 29e1bc8] rename + 1 file changed, 0 insertions(+), 0 deletions(-) + rename bigfile => newname (100%) + joey@darkstar:~/tmp/demo#master(unlocked)>git log --pretty=oneline + 29e1bc835080298bbeeaa4a9faf42858c050cad5 rename + a195537dc5beeee73fc026246bd102bae9770389 git-annex adjusted branch + 5dc1d94d40af4bf4a88b52805e2a3ae855122958 add + joey@darkstar:~/tmp/demo#master(unlocked)>git log --pretty=oneline master + 5dc1d94d40af4bf4a88b52805e2a3ae855122958 add + +The commit was made on top of the commit that generated the adjusted branch. +It's not yet reached the master branch. + + joey@darkstar:~/tmp/demo#master(unlocked)>git annex sync + commit ok + joey@darkstar:~/tmp/demo#master(unlocked)>git log --pretty=oneline + b60c5d6dfe55107431b80382596f14f4dcd259c9 git-annex adjusted branch + 9c36848f078a2bb7a304010e962a2b7318c0877c rename + 5dc1d94d40af4bf4a88b52805e2a3ae855122958 add + joey@darkstar:~/tmp/demo#master(unlocked)>git log --pretty=oneline master + 9c36848f078a2bb7a304010e962a2b7318c0877c rename + 5dc1d94d40af4bf4a88b52805e2a3ae855122958 add + +Now the commit has reached master. Notice how the history of the adjusted +branch was rebased on top of the updated master branch as well. + + joey@darkstar:~/tmp/demo#master(unlocked)>ls -l + total 1024 + -rw-r--r-- 1 joey joey 1048576 Mar 3 17:09 newname + joey@darkstar:~/tmp/demo#master(unlocked)>git checkout master + Switched to branch 'master' + joey@darkstar:~/tmp/demo>ls -l + total 4 + lrwxrwxrwx 1 joey joey 190 Mar 3 17:12 newname -> .git/annex/objects/zx/X8/SHA256E-s1048576--44ee9fdd91d4bc567355f8b2becd5fe137b9e3aafdfe804341ce2bcc73b8013f/SHA256E-s1048576--44ee9fdd91d4bc567355f8b2becd5fe137b9e3aafdfe804341ce2bcc73b8013f + +Just as we'd want, the file is locked in master, and unlocked in +the adjusted branch. + +(Not shown: git annex sync will also merge in and adjust changes from remotes.) + +So, that all looks great! But, it's cheating a bit, because it locks +all files when updating the master branch. I need to make it remember, +somehow, when files were originally unlocked, and keep them unlocked. Also +want to implement other adjustments, like hiding files whose content is not +present. From c8f777a59324202ccc53dac698b8825318d9312b Mon Sep 17 00:00:00 2001 From: edward Date: Fri, 4 Mar 2016 10:44:54 +0000 Subject: [PATCH 07/58] fix link --- doc/devblog/day_369-370__paddling_furiously.mdwn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/devblog/day_369-370__paddling_furiously.mdwn b/doc/devblog/day_369-370__paddling_furiously.mdwn index 59dc8dda0a..5321079002 100644 --- a/doc/devblog/day_369-370__paddling_furiously.mdwn +++ b/doc/devblog/day_369-370__paddling_furiously.mdwn @@ -6,7 +6,7 @@ And then more lock files today, since I needed to lock git's index file the same way git does. This involved finding out how to emulate `O_EXCL` under Windows. Urgh. -Finally got back to working on [[adjusted_branches]] today. And, I've just +Finally got back to working on [[design/adjusted_branches]] today. And, I've just gotten syncing of commits from adjusted branches back to the orginal branch working! Time for short demo of what I've been building for the past couple weeks: From f49570857cf7125d44a41594e8eb56caaf16c6d2 Mon Sep 17 00:00:00 2001 From: "frederik@ffbea6a549cb3f460d110386c0f634c1ddc6a68a" Date: Fri, 4 Mar 2016 14:06:17 +0000 Subject: [PATCH 08/58] Added a comment --- .../comment_1_0b15f7a8c3bca87dcbf748a229e13a4b._comment | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 doc/forum/Undo_git_merge_git-annex/comment_1_0b15f7a8c3bca87dcbf748a229e13a4b._comment diff --git a/doc/forum/Undo_git_merge_git-annex/comment_1_0b15f7a8c3bca87dcbf748a229e13a4b._comment b/doc/forum/Undo_git_merge_git-annex/comment_1_0b15f7a8c3bca87dcbf748a229e13a4b._comment new file mode 100644 index 0000000000..bbc6117f7b --- /dev/null +++ b/doc/forum/Undo_git_merge_git-annex/comment_1_0b15f7a8c3bca87dcbf748a229e13a4b._comment @@ -0,0 +1,8 @@ +[[!comment format=mdwn + username="frederik@ffbea6a549cb3f460d110386c0f634c1ddc6a68a" + nickname="frederik" + subject="comment 1" + date="2016-03-04T14:06:17Z" + content=""" +git revert -m 1 [sha_of_merge] seems to have done the trick +"""]] From 5716c3992804f35f6561756e7fd5b732bf3677a2 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Fri, 4 Mar 2016 11:31:26 -0400 Subject: [PATCH 09/58] thought on reversing commits to adjusted branch --- doc/design/adjusted_branches.mdwn | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/design/adjusted_branches.mdwn b/doc/design/adjusted_branches.mdwn index ba3e784214..f79a7f1abd 100644 --- a/doc/design/adjusted_branches.mdwn +++ b/doc/design/adjusted_branches.mdwn @@ -209,6 +209,12 @@ which to not delete when reversing it? So, a reverse filter may need some state that was collected when running the filter forwards, in order to decide what to do. +Alternatively, instead of reverse filtering the whole adjusted tree, +look at just the new commit that's being propigated back from the +adjusted to master branch. Get the diff from it to the previous +commit; the changes that were made. Then de-adjust those changes, +and apply the changes to the master branch. + ## push The new master branch can then be pushed out to remotes. The From c2a0a900dda20300fafadad0d8e37f6127b6c530 Mon Sep 17 00:00:00 2001 From: workspace Date: Fri, 4 Mar 2016 20:44:26 +0000 Subject: [PATCH 10/58] Added a comment: same problem --- ...ment_2_825b72391117f88062a585684cf62eeb._comment | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 doc/tips/largefiles/comment_2_825b72391117f88062a585684cf62eeb._comment diff --git a/doc/tips/largefiles/comment_2_825b72391117f88062a585684cf62eeb._comment b/doc/tips/largefiles/comment_2_825b72391117f88062a585684cf62eeb._comment new file mode 100644 index 0000000000..316f33c2af --- /dev/null +++ b/doc/tips/largefiles/comment_2_825b72391117f88062a585684cf62eeb._comment @@ -0,0 +1,13 @@ +[[!comment format=mdwn + username="workspace" + subject="same problem" + date="2016-03-04T20:44:26Z" + content=""" +I have the same problem: +the annex.largefiles is ignored by \"git add\" when set in .gitattributes +allthouch git check-attr does list it. + +but it works when set with git config annex.largefiles + +git annex version 6.20160126 +"""]] From d6bfa533b566c83416fa3e79714699b199d3457b Mon Sep 17 00:00:00 2001 From: "ellis@9dd4c3615b5ff78a457c5832488610886fd6b255" Date: Sat, 5 Mar 2016 12:18:48 +0000 Subject: [PATCH 11/58] --- .../git-annex:_failed_to_lock_content.mdwn | 105 ++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 doc/bugs/git-annex:_failed_to_lock_content.mdwn diff --git a/doc/bugs/git-annex:_failed_to_lock_content.mdwn b/doc/bugs/git-annex:_failed_to_lock_content.mdwn new file mode 100644 index 0000000000..57e0e5ab62 --- /dev/null +++ b/doc/bugs/git-annex:_failed_to_lock_content.mdwn @@ -0,0 +1,105 @@ +### Please describe the problem. + +Cannot drop unused files on a USB drive, failing with the error message "git-annex: failed to lock content". + +### What steps will reproduce the problem? + +1) Installed stand-alone verison of git-annex on Ubuntu sometime last month +2) Created a repository on my main HD, upgraded to v6 +3) Added files to it +4) Created a USB (vfat) repo using the webapp without encryption; stopped the webapp, and ran `git annex get` on the USB repo. +5) Saw that I had added some files to the repo by mistake, and used `git annex unannex $FILES` on the main HD, then `git annex unused`, then `git annex dropunused 1-101` +6) Re-synced both repos +7) In the USB repo, `git annex unused` showed the same list as on the HD. +8) `git annex dropunused 1-101` then fails +9) Installed the latest stand-alone version (6.20160229-gbe4820c) +10) tried dropping again, didn't work; reboot the computer; tried dropping again, didn't work. +11) ran `git annex upgrade` on USB repo, tried dropping agian, no success + +### What version of git-annex are you using? On what operating system? + +* git annex version 6.20160229-gbe4820c +* Ubuntu 15.10 + +### Please provide any additional information below. + +[[!format sh """ +/media/ellis/USB04/repo/taiji-lib +% cat annex/unused +2 SHA256E-s562039928--04903c0b7d4e16062b3dc0bf17a84ce7943545d9437b80947ff98a3d3483e66e.AVI 1457129072.853555s +101 SHA256E-s38464078--0db38599ed526d248857015c7b8e1b177af646939f8e0c8004b17a931ce2e101.wav 1457129072.853555s +... +44 SHA256E-s561941624--fdf6f89d9403464d4c494eac67fc1525aa6b9b0adc96be99f7d42e7f5472e44c.avi 1457129072.853555s + +/media/ellis/USB04/repo/taiji-lib +% git annex dropunused 101 --debug 13:09:28 +[2016-03-05 13:09:28.675403] read: git ["--git-dir=.","--literal-pathspecs","show-ref","git-annex"] +[2016-03-05 13:09:28.677635] process done ExitSuccess +[2016-03-05 13:09:28.67773] read: git ["--git-dir=.","--literal-pathspecs","show-ref","--hash","refs/heads/git-annex"] +[2016-03-05 13:09:28.679775] process done ExitSuccess +[2016-03-05 13:09:28.680234] read: git ["--git-dir=.","--literal-pathspecs","log","refs/heads/git-annex..aee0b39b5232c369721c08eb782a7143ba2f8901","-n1","--pretty=%H"] +[2016-03-05 13:09:28.685879] process done ExitSuccess +[2016-03-05 13:09:28.686006] read: git ["--git-dir=.","--literal-pathspecs","log","refs/heads/git-annex..2b2b2747a6533f115867cc7a70a426764fc90286","-n1","--pretty=%H"] +[2016-03-05 13:09:28.688135] process done ExitSuccess +[2016-03-05 13:09:28.688227] read: git ["--git-dir=.","--literal-pathspecs","log","refs/heads/git-annex..4f4acf1555539a7bcb520e4befbeab803f220f67","-n1","--pretty=%H"] +[2016-03-05 13:09:28.690357] process done ExitSuccess +[2016-03-05 13:09:28.691327] chat: git ["--git-dir=.","--literal-pathspecs","cat-file","--batch"] +dropunused 101 git-annex: failed to lock content: ./annex/objects/97e/78c/SHA256E-s38464078--0db38599ed526d248857015c7b8e1b177af646939f8e0c8004b17a931ce2e101.wav/SHA256E-s38464078--0db38599ed526d248857015c7b8e1b177af646939f8e0c8004b17a931ce2e101.wav: openFd: permission denied (Permission denied) + +/media/ellis/USB04/repo/taiji-lib +% ls -l ./annex/objects/97e/78c/SHA256E-s38464078--0db38599ed526d248857015c7b8e1b177af646939f8e0c8004b17a931ce2e101.wav/SHA256E-s38464078--0db38599ed526d248857015c7b8e1b177af646939f8e0c8004b17a931ce2e101.wav +-r--r--r-- 1 ellis ellis 38464078 Mar 4 18:32 ./annex/objects/97e/78c/SHA256E-s38464078--0db38599ed526d248857015c7b8e1b177af646939f8e0c8004b17a931ce2e101.wav/SHA256E-s38464078--0db38599ed526d248857015c7b8e1b177af646939f8e0c8004b17a931ce2e101.wav + +/media/ellis/USB04/repo/taiji-lib +% strace -e file -f git annex dropunused 101 --debug +... +[pid 4646] openat(AT_FDCWD, "./objects/pack", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3 +[pid 4646] access("./objects/pack/pack-80b045ea51312a9d40fdefd0c76ef54d494cd5c1.keep", F_OK) = -1 ENOENT (No such file or directory) +[pid 4646] stat("./objects/pack/pack-80b045ea51312a9d40fdefd0c76ef54d494cd5c1.pack", {st_mode=S_IFREG|0644, st_size=828068, ...}) = 0 +[pid 4646] access("./objects/pack/pack-69caefc604cfbcb2f374ab0b4266f444fec4930f.keep", F_OK +[pid 4636] --- SIGVTALRM {si_signo=SIGVTALRM, si_code=SI_TIMER, si_pid=0, si_uid=1, si_value=0} --- +[pid 4646] <... access resumed> ) = -1 ENOENT (No such file or directory) +[pid 4646] stat("./objects/pack/pack-69caefc604cfbcb2f374ab0b4266f444fec4930f.pack", {st_mode=S_IFREG|0644, st_size=55237, ...}) = 0 +[pid 4646] access("./objects/pack/pack-f6711fe647796d2143d12b6f915686d373f4e69b.keep", F_OK) = -1 ENOENT (No such file or directory) +[pid 4646] stat("./objects/pack/pack-f6711fe647796d2143d12b6f915686d373f4e69b.pack", {st_mode=S_IFREG|0644, st_size=116702, ...}) = 0 +[pid 4646] access("./objects/pack/pack-31185be34b1a30abb4b6e427c1ec924cfee300af.keep", F_OK) = -1 ENOENT (No such file or directory) +[pid 4646] stat("./objects/pack/pack-31185be34b1a30abb4b6e427c1ec924cfee300af.pack", {st_mode=S_IFREG|0644, st_size=116197, ...}) = 0 +[pid 4646] getcwd("/media/ellis/USB04/repo/taiji-lib", 129) = 34 +[pid 4646] open("./objects/info/alternates", O_RDONLY|O_NOATIME) = -1 ENOENT (No such file or directory) +[pid 4646] open("./objects/pack/pack-f6711fe647796d2143d12b6f915686d373f4e69b.idx", O_RDONLY|O_NOATIME) = 3 +[pid 4646] open("./objects/pack/pack-31185be34b1a30abb4b6e427c1ec924cfee300af.idx", O_RDONLY|O_NOATIME) = 3 +[pid 4646] open("./objects/pack/pack-80b045ea51312a9d40fdefd0c76ef54d494cd5c1.idx", O_RDONLY|O_NOATIME) = 3 +[pid 4646] open("./objects/pack/pack-69caefc604cfbcb2f374ab0b4266f444fec4930f.idx", O_RDONLY|O_NOATIME) = 3 +[pid 4646] open("./objects/ae/e0b39b5232c369721c08eb782a7143ba2f8901", O_RDONLY|O_NOATIME) = 3 +[pid 4646] open("./objects/1d/ca126189c826e37b03897754fab7e8a8687683", O_RDONLY|O_NOATIME) = 3 +[pid 4636] stat("./annex/unused", {st_mode=S_IFREG|0644, st_size=11160, ...}) = 0 +[pid 4636] open("./annex/unused", O_RDONLY|O_NOCTTY|O_NONBLOCK) = 11 +[pid 4636] --- SIGVTALRM {si_signo=SIGVTALRM, si_code=SI_TIMER, si_pid=0, si_uid=0, si_value=0} --- +[pid 4636] stat("./annex/badunused", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0 +[pid 4636] open("./annex/badunused", O_RDONLY|O_NOCTTY|O_NONBLOCK) = 11 +[pid 4636] stat("./annex/tmpunused", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0 +[pid 4636] open("./annex/tmpunused", O_RDONLY|O_NOCTTY|O_NONBLOCK) = 11 +dropunused 101 [pid 4636] stat("./annex/objects/97e/78c/SHA256E-s38464078--0db38599ed526d248857015c7b8e1b177af646939f8e0c8004b17a931ce2e101.wav/SHA256E-s38464078--0db38599ed526d248857015c7b8e1b177af646939f8e0c8004b17a931ce2e101.wav", {st_mode=S_IFREG|0444, st_size=38464078, ...}) = 0 +[pid 4636] stat("./annex/objects/97e/78c/SHA256E-s38464078--0db38599ed526d248857015c7b8e1b177af646939f8e0c8004b17a931ce2e101.wav/SHA256E-s38464078--0db38599ed526d248857015c7b8e1b177af646939f8e0c8004b17a931ce2e101.wav", {st_mode=S_IFREG|0444, st_size=38464078, ...}) = 0 +[pid 4636] stat("./annex", {st_mode=S_IFDIR|0755, st_size=32768, ...}) = 0 +[pid 4636] open("./annex/keys.lck", O_RDWR|O_CREAT, 0666) = 11 +[pid 4636] stat("./annex/keys/db", 0x7f2247d0ceb0) = -1 ENOENT (No such file or directory) +[pid 4636] --- SIGVTALRM {si_signo=SIGVTALRM, si_code=SI_TIMER, si_pid=0, si_uid=9, si_value=0} --- +[pid 4636] stat("./annex/objects/97e/78c/SHA256E-s38464078--0db38599ed526d248857015c7b8e1b177af646939f8e0c8004b17a931ce2e101.wav/SHA256E-s38464078--0db38599ed526d248857015c7b8e1b177af646939f8e0c8004b17a931ce2e101.wav", {st_mode=S_IFREG|0444, st_size=38464078, ...}) = 0 +[pid 4636] open("./annex/objects/97e/78c/SHA256E-s38464078--0db38599ed526d248857015c7b8e1b177af646939f8e0c8004b17a931ce2e101.wav/SHA256E-s38464078--0db38599ed526d248857015c7b8e1b177af646939f8e0c8004b17a931ce2e101.wav", O_RDWR) = -1 EACCES (Permission denied) +git-annex: failed to lock content: ./annex/objects/97e/78c/SHA256E-s38464078--0db38599ed526d248857015c7b8e1b177af646939f8e0c8004b17a931ce2e101.wav/SHA256E-s38464078--0db38599ed526d248857015c7b8e1b177af646939f8e0c8004b17a931ce2e101.wav: openFd: permission denied (Permission denied) +[pid 4638] +++ exited with 0 +++ +[pid 4639] +++ exited with 0 +++ +[pid 4637] +++ exited with 0 +++ +[pid 4636] +++ exited with 1 +++ +[pid 4623] --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=4636, si_status=1, si_utime=1, si_stime=4} --- +[pid 4623] +++ exited with 1 +++ ++++ exited with 0 +++ + +"""]] + +Could the problem have something to do with the file having permission 0444 and trying to opening it O_RDWR? + +### 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) + +Been using it since your kickstarter campaign! From 1d6ab9b065eda53d4d0820cfd560a70d7b715e65 Mon Sep 17 00:00:00 2001 From: "ellis@9dd4c3615b5ff78a457c5832488610886fd6b255" Date: Sat, 5 Mar 2016 12:19:50 +0000 Subject: [PATCH 12/58] --- .../git-annex:_failed_to_lock_content.mdwn | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/doc/bugs/git-annex:_failed_to_lock_content.mdwn b/doc/bugs/git-annex:_failed_to_lock_content.mdwn index 57e0e5ab62..f383f30ffd 100644 --- a/doc/bugs/git-annex:_failed_to_lock_content.mdwn +++ b/doc/bugs/git-annex:_failed_to_lock_content.mdwn @@ -4,17 +4,17 @@ Cannot drop unused files on a USB drive, failing with the error message "git-ann ### What steps will reproduce the problem? -1) Installed stand-alone verison of git-annex on Ubuntu sometime last month -2) Created a repository on my main HD, upgraded to v6 -3) Added files to it -4) Created a USB (vfat) repo using the webapp without encryption; stopped the webapp, and ran `git annex get` on the USB repo. -5) Saw that I had added some files to the repo by mistake, and used `git annex unannex $FILES` on the main HD, then `git annex unused`, then `git annex dropunused 1-101` -6) Re-synced both repos -7) In the USB repo, `git annex unused` showed the same list as on the HD. -8) `git annex dropunused 1-101` then fails -9) Installed the latest stand-alone version (6.20160229-gbe4820c) -10) tried dropping again, didn't work; reboot the computer; tried dropping again, didn't work. -11) ran `git annex upgrade` on USB repo, tried dropping agian, no success +1. Installed stand-alone verison of git-annex on Ubuntu sometime last month +2. Created a repository on my main HD, upgraded to v6 +3. Added files to it +4. Created a USB (vfat) repo using the webapp without encryption; stopped the webapp, and ran `git annex get` on the USB repo. +5. Saw that I had added some files to the repo by mistake, and used `git annex unannex $FILES` on the main HD, then `git annex unused`, then `git annex dropunused 1-101` +6. Re-synced both repos +7. In the USB repo, `git annex unused` showed the same list as on the HD. +8. `git annex dropunused 1-101` then fails +9. Installed the latest stand-alone version (6.20160229-gbe4820c) +10. tried dropping again, didn't work; reboot the computer; tried dropping again, didn't work. +11. ran `git annex upgrade` on USB repo, tried dropping agian, no success ### What version of git-annex are you using? On what operating system? From 40c15871d50a16d537071d2d059c6d4a896e0861 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sat, 5 Mar 2016 11:23:17 -0400 Subject: [PATCH 13/58] remove LGPL, after removing the LGPLed file --- doc/license.mdwn | 2 +- doc/license/LGPL | 502 ----------------------------------------- standalone/licences.gz | Bin 55882 -> 55879 bytes 3 files changed, 1 insertion(+), 503 deletions(-) delete mode 100644 doc/license/LGPL diff --git a/doc/license.mdwn b/doc/license.mdwn index 837fd8c3b9..45e33714aa 100644 --- a/doc/license.mdwn +++ b/doc/license.mdwn @@ -9,6 +9,6 @@ under the AGPL as a whole. git-annex built without the webapp does not include this code, so remains GPLed. git-annex contains a variety of other code, artwork, etc copyright by -others, under a variety of licences, including the [[LGPL]], BSD, +others, under a variety of licences, including the BSD, MIT, and Apache 2.0 licenses. For details, see [this file](http://source.git-annex.branchable.com/?p=source.git;a=blob_plain;f=debian/copyright;hb=HEAD). diff --git a/doc/license/LGPL b/doc/license/LGPL deleted file mode 100644 index 4362b49151..0000000000 --- a/doc/license/LGPL +++ /dev/null @@ -1,502 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/standalone/licences.gz b/standalone/licences.gz index b126f88c0e87aa518b672a37e3fbe6671d251d2c..188df62e0be1dd4af1c455585efe6a1f23de83f3 100644 GIT binary patch literal 55879 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 literal 55882 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 z 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ⅇfPPOs#U6??ydkz!(BQI{G|9`xXb{ zS^P>;lxE@~mm)&Q&BJ6kykI&z1VaS^fN`LSy5tUo7dXjDEvmavZ_PfbH?%HUv?gH7 ziCa%1d7f%)r_PLjAu{h!({M0>tkP4!Bbq%4BG=>lc6!UyDEoKE1YGHLOaS{CbY>qA z7Q$KykNTfIJsPIed`BYQx$i3arX&^o|L0q$qj%0b~1fsul}GM3ho zV2x1Rtb&j8+JkF2pmFMn9vek3FWI2PC)J`%OhS&Go!dyIeT!&@S9C0jsCk*5U+@fq zYhvv5R{;Jx_x})TxfI$qAI^hs^uD;_4G-Oru|{_YL#e0fwPeGv{HRYwEqo6EAy+5^ zJ-sn$#GXW6L%7ZXdEA2aN-wEL5|a6B2IL`M719JGjfP}W+Di_g_`I-qlAqI`R>n7^ zMU?t*uKB!VPNPN8us_5GMj<7aGmn?Lh~mau-ED(d)0+q71!rI)H%PCHa_Rx##o;HU zUT0s<2K-qfFQL(Tpw3#-T6p!?8CEG(tOq38eUE45r?gwG?d328f0&}QWXh*P(5v}B z&#nwe^cmO)um-Gtv6LY7-dO%3Xm%$88uNMWRH-TJfn+V;z@_kCVu5SDo*jVV@3QEy zk|ucf*_=$E1Yjn=u-6@m3h^fov_n;fTwS}qyP@#nf4oB3#t5}}?cV4%7Kh-;z-d_l zJ8f;1s>Wew(cXB{`s;!2y?p$LL-3SnQVU~C`So*79ylNi(=_=c*PyQUgu}Ha?snfm zG3@LLhT2Q3=T4nVNi1jFMF~)uwpvSH-9)Y0gQ=E@NRcSVIM}WZtq5TfuM#x`BMJ`C zk7!RC)_Mqo$nZAEwMNlFIe632XOQ3s@)R+6(L%yJx(rn)ISM}XsDZK5r|5obq!sU)L@AsD}UV%fZ%NBBl0}zWz`g_@;3L-bW zCB1?MUz+;Ya=kRK%2Gnk%c|02e<{>3i`C9Us9YH?BYY<~W6RQ2W&&u?3%O%65s+5k zp9#63DDBEo?0IvrP$u{3hm$IGohKp1T^1{o<|ys}s}&dnmBhf!BigpNcXE<&SlOHt zs_c!aGuY0lA^%BLOv(iN+p}jyf>#h9H%hB=XuS+s`b$B4}t*>F_`_+NpduRb}iM5j0d;iR6tpqv~ zNOcGK0ID@>i)8LPxMD#0hIqr9r)4s)j@9}n7)tNmIR}og@9(5doiP}O??V@r%jPqy zjSY;ppb>=VooCV~WKCrL~iTm9oNUTdsN6ny8UAxK`WTA9?Ih zecH?@(%QBwA@bqUrj^`pqoeZp(DQF;&eHg)s zM&c9fAx3QI@OKVUrn3#{L56t-700IiL`mPn*u>vL^3M`g1lwgKbC~8O-~*#8q0nZq z{sY{oQm%pe>QNvUg$-cyWN`mJ_z;?dmOWSSF=R^qJ?6!a0ei5|!N(WQ|0G`ceSd!X zdOZ%|gXoKs-G%+cPjY__`R#d^y4Zhj@#(pL+1{b@7iI7mrV3Ue5QbqX*d+E2oE_lY1H6-X^=tW!fv|hlhtx z=Aa)T6YKN%@DBrCr(D}gD85cD_)Y5IVPIjS@M@&fh-=cgF%GX@MCj57=tD_ zIWgitr$=k_HTa$?Ed>^%#N|GBqf?AkmA?dp<$nZ(&i@b)uvVolj(eQ{i-73TB(Eu! z7hV-jlh>u|(m?u5_%$GCa<>Qmj{(7QZ}h(nh^a+N*pC{&j4-UGT`72bR5%$QNRCh3PQr|Jsex=4@zorI`S_C0so9d z6YTc7!h5sFD{qKn{WN>;$xivZ&TjlQs2|#<`6gLYD2#{cC2k!kzEnH0`!qHVT2HE* zekfM1^F@{gHd>^1+8=t_PxL~{7XlS-|BfTXIlDHKkt*;ZB6&kb_^Z+r;wkpCxR zb{e~B2-ga(!*3?gLsWkV1um@A1))g@H~=cv8M#rb>G#y~>0pI+>KnLK^Yf774F17k z0CLWg+>ktL?~cdqna-`W{I8>mVH9e3RqZ*%1YAKS?jiY84qc-%dW*u3aZ)spwk%zq zLtc|M938H&D>ZFiX^z9Z`hoQQTa7Hcimr~jZY=mht?pY20_kMsm%Q<6Hrr~f|3 zaBqLEtNJy!N&46A4<3qNYcjqIEk~ZOesp0To1n7rsztA!$&l`Au^8dt6B91Rw(C-S zYR?^?I>d*1+n{LmgnHyFz=wPPX3kDGA;bp4)20yWh#TSdsJ#Q^;ShzG%y7Ia%UuXx zlI39E(?QR!xgOFmqyFXrNhCbtySyfs!PkX4p_|NzM0R)HVMxDOj^cch#zS4WK@8;n z-!KG4t)1`w&J*AzbhCd7HPma`8OF%aQjp_2K@Je%^Dhixfj_2Fyb7S>M6WHphJm*x zc|qz`K8f+YjdJ#s#dyU2FcvQZBp3)&Pqe$|+)LTL7@&#+(M_E}e2p0rtXoo(e5I2h z-6SZ%J4OAeh$N7aFXkwH_s=KD8V-C-lD_QFs)t}3A1aZgQj)zFS~7t?0#F0?X8^+lA(;lHXVD! z5tf2*2EmOKdp>L$%`>b5Bp2P4HQdF>3}bCO>_Gue+phoGO(H777JxlT-DRMh#96BC zuc15$(TIt6Km6L}%JlQiA)+nX>W0lG=>hMn@|Hdg;Un9+FXr%U4lnV%{9C^DGA<6! z%cVI!AZ<`F>jAtqx+MRmp2*%V2H#*;B!u07+Z`{n1xPCB3&u(w2|2k zuzNQj7%iL)G)Gg)S*BZdR6&ZyH+Hs~LI!O|j`!xL7RiTRz``C8EGLpYy636`;rtS@ zrzYZh=Ea?10?QzpvfCjZB^#rCbRgvPIoDT-8y-ULUN^{=w3Uc36u+cmb2w@#Lj1dR zIErLh8K6A*_{ngp3;^bkWXb}JUuo;8FeqBFRV)2n6mGI|DNX4|)f}82M*aehXl5?r zqP7u41DZ$9G}BPNuWE_nHfqUnzCoy(=_q0W% zK~#wC)TCbCip5e(-_4lE?lul1Xo*YR##&D6s(=sy`CU!islsVD$n6A|ygM7DxKcrzW-#<4J7ns8E2!}8R@ zr--d49vDS?ru#QAVOc`d)>mGVaCgPL@%OWZO7Bzs>A*;g**vba=x_s7q9x*g@kFBS z9hEHF_9dhUg8}pjWLWP{%FltEuJCG*Xebnusa`PJA+uyez}m`e=_z{s2S;vs(o)2L zIaO5K#sO}Dvk3mod=A(TMj>KNfo1jYdh%6Lk1m>sSd7!9u%xU2WgJ#|*%D%|l*4@A1wxGlek z&QL9i+gQf0BhxeWPPB;xj3!-^^>N@lcob&4shsQJ+=03&k{&eFG#s4_O#ryxDMZ$9 z$kLs3gkW}|TtP$(=1j{!@8^0_(`}(sDU6}2*`fqR)pjB*vRKxZUcNOLRs-+3Dq5Hc z_mW*MH@Zl19>=rUZAW{W`}=2x%}aBMwj`8hX}FeF8oCJfi25rLI>rSbb@RiSoHVr7 zqj;$}r_j=yf_-*REI4-;0sd(T{qr$%X2NomN$#s5g4I}`tTVL((*~*CpP5Gd3}~NW zINNB!XkR_zmM_DbiBb$^Fl3erhih0j@0XZl*s%d=ZL0G|#I5Y{YjjIjZ;nwyEvq|&CduofoPzL|d0=_na9V*0 zio&=xFU#zE=jHWkV{8?hUB!rURPK7okkr#c+{)wV68P{BuW^IWrjc{NJE;NI4OK#M zW*YT`+#PNfy8Jha7a{;K?b~h5*%p??T)J~S{3KNopb_H|p>j3D5we^1{v9)@RYFwe zn@*@$OG~Oc%KXXYF26UgR3p!$zCf>;K%3?eB1thMfLoZ~MAExVYFV~&g@(zbT^t2} zaB+QSz&Ktac2Mg+ku%D->V4a$uB)qiD`0hVTW9cBN;8bkSb`vWeTRcFP&%10rI z`U~?Q6pI7%ARtYMt<1>k>#+G4;8pHGmF#II;i9@3#j#ulC;fzp^;d43z1vN@?J!6& zkSucCnqK_NZf7?$#XlEcHR$*P(~kup@)@@vT~7kZX49m20{PZ_z<+^tk)2#4YWL{Y zA1br06#np|=zFD$PyaJ$ATW2*sXi$RxWE_W`Wu;5!`p&6kuP`(5qMw1 zqwef2T?8!`jiHQp(PH0wF!F?q@`Eu2Q^aPIYZ}1;jP+3Lk0q*hvcC`@*KvRM8AX@IDF$)ryg%ZEH$YKbL&f+M9>$ z^b-xAUnxeqJJtyx(L8R+^lLH#gov&;B_+*m$cl=HZ0Qa+&{0?A_?q|rOA~#DeKki$BNwIgjeCl+3t93D)}XdqoyNRCHs!mIpEPMH4pK0N(6 z1MK2H{m?8Pb z>&m+(8-hxZ!A@GqZh%>q1kp_zsTG&;DYo7oyLVMn-(YtZy;p?mNL+xW;f(I9EM=w; zHNj^LQ2{5})7WWR1H1Ckj>5`5vA;aUr~ff-IF{tD62*lixB}*eFJmmo5=>ENx%*_i zqS8~<7;`1z977o`sYjRGEcWf}FNEX9vFebHQapn+QgE9|=)-?`*OPP*2Ty^CJXm>YKtn-`;1Mjj_-Old z*_4zvBy;d&KvM}|<7A_b;{%>tF(Ky|6AaKw#<($J=>TI5rs|$B1>s`Qsve{4g)!AH zPJw7YGD4hKo%Q@FkE*8d4^-h*W;wzp*=k$`ss{LrAFpd)?RGP($boO7axc2F=!1>~ z>V_mr@bG~)86$C!7}+PEq9@V=;lWg^O6&x#wo|0RrgAG-8;M4^cr&L9Po?^@m1NOV zhcy@3NbvZ)_*~+RHOCbOwxvHeZxDb_)H z$V#k~Ucy-!hE2eKG;RgXxOsx%v6l2fZ$s|>^d8vhcnP|iKI|IBB5}` z4#_i6*)20*YI`Xofde07t7mJ*TEN#bU!bw$CsB+5+e9==et2SzQ7Wv0dO3V|3@T3G zvw|&9)>^cJ1=tmJlq)@s)Zj}Xq7*Z49u-~}E4W)4*;CHY3mPP@D^B)`>XQsjZ*24= zesyp&bW}IOdjkGLouCa$LIbuo11eLC3xlc<=JYwVee1GD)}0~E3NA}I(_J~LO3)(%H832T6e+tlTsuZ_ zt^I}b@HImGXL-V(}AqgcD#-Qpu*!wbvx zG9od^`tr-sM#SOQ>n9Svvro^b<>S%Vh{J)bWhs-?sx!g7jRi>0cSa9w# z)F|2N4sWndBCe2iVRoK!cG{hGgEm7X{fM=#@hVJpnolj=Pgp9I} znUwt31DXy*?3^vHHbfoJxd<&W?G5Wn$pLv$@};r_P&ek;wDj5)(`&NMYK^D?ZA~QB zLlbb*hH3gGteG(&J)5mAG$CmyZp+Q2fbYVasX(l{1X)i4wGF4R+03;fRx?vNyhZ8N zUZdcZvEn|anavbRup@q*;cCrM;cg1U(N^h;eA=rwX}l*OTQpVR{j~JzM63ueB&RjT zq?pSMZ#gsduL71vE#V$2o-k4YbWMlV*q>8eWo#;{7CG)F?DEBp}ZBn_*dz5o?I$XZ3~xSDoo@z9v&Ask^gJVN@)z2A1f8>ZoV zFoUI81C;8hM*xK{C~$6HK?{S{!mR-<_cqVG~sbT$$r6B9BtRQj_^+$`}Pl1}sXcm5c`_HKVF|gg_H=k);LNz+74eiYJRNZUHq9Tm>+_Y))d|DFhCGSLyD~5$o2DQFaQf}VlAGaY}iQijEohJo{U&~ zBLeFgGbbwrr{dbmGf44EYero?$Oss<%dtPNV~=*+^4WaxO=w1Rk)KZ>G*9eQe8)W*U&{)+Q?)ZB=Cwlfq@-nCPFX+ z2v$Cmzzi#<0pL@N2A9@l_5)qQpIEgM?sNPm*L}lw5He=$c(YLADBZ)vH^D z9aHNHGSa8ekZw55Q+%RvD%+gxWkBBvfnwcdJO$(`=r1V>(vyG4Lz}@*z6K28lJ}#O?Io1 zK@lnr))60<9u5sQtx1??`Du}AHj{?K%^bUlPd|0etM$5d_?vGGt zrDo;@RF!04jQXjgZ`LA>n>2YC*3_p3@e?P8C1`6h*$GwBh5upB;czq((9~{^Xzk#0 zmXNOpp30PS*lcO2R884@BPZHgb>HDc_bzdR@ZM$`7pDH(B`KRomC7XoX#MDGibO5v z;L9XW|4eb(EO0jbk5WodL|g%cGvGhO`hdg{>h$1*Kv?BoZOQ?$mAX#kY z`kB>=q?RBn@;A-+wa=8&BDNqC_$jQBV9^P>09-=1%7^9(P|=VRWOx>`$D&Wpd(8wK zx{X09rXxg$Xf!NpMQfKPqjC-K^haut_LlX+e!z(-a2Fe_ zdZ5e}V+LUR;?oFFH$?gv>8!PZ=PgJxYFhV?S^YM-uG++YmKzT|^s-vBj zTw?iU#sX!#3~8iwD_DEGo_S});#Q#SF1b_0Pny3fX{<@9%wTMHhLQHROpHC+LT<$qhYvqRWMVcG$S1Xa9~*?rvms3P6W9HtxAmo%-Ss0F z^`%G+{T&GLQHa(Z$36egl>&lA^DTeR`fL(6%~XU9W&>3#D*M?ca(_j_OC)$PfSQV_ZCgQAP&cLkL zz^+EuKeC3X0ir_P_0spk6FBWHk|}#JWOTbt;fAvTe@n8dB8awKY={h0K~NTv9aJ=I z0ZBy+5d;|I;x%FZR^hAF$;GY~nK|mSK|t^MfITqKCmYp^1C8U(@bfQ=fa6Wz%h!CT z;DXd0{&wiTFLAH0vunUl^yBw@_v;sXg`re+PcMFL|@Cv%c+* zoY~JG;%0t`J)7|MAHbonuUQbepDAe2_lmox{=>76!nocahpVsn{99iVcVCmW5B$+> ze9)t>*utAw7}p=-w2wk87hi6NpTo9Ye4(!%)RPw*#9q7H7jN#STWv#c_6XBh1MgkB z^A9!7-CN1Gp7{H(CvS{hcI2Mj&~xubTs2}3-(|^1AN-t`>bWkvz+-P{l3VPM&djYZ zysaBuWlr%>o%O-rQLU9pH(jbLOAGI{&?m+TDBa~c89NWRm02;ym@Scc+0s!FLlLwn z*Q^tnpy2?@iy%)o6_qIDT(7OUDW2GKjlCIfrRc=K&po`PP2-?m>|pfH=X()|qi9zC ze_(Yyvq=n}cH}4Pea#|Jc&b(F#ZQFGAp7jKS$Qt%cgBD=apqv4L}``^^N_q4z z2O;2(x&1rAWU%>4Yf0l!MtxbKe>jg`5jfAE|A>+LFL$KO{9w&B;e*GtAuqbUqUZAfX1_E z08Cc2IXEHh5FH(k7BDX!^0|N!Di^d|ND#s8BAG_0B1ig9uk}5ChC}J)FsHR5fNk#( z%@e*MpF#mw2S%|aK0XklyQ*X3>MyiGHce@@uz5rm*~O$8}Ww}CIiZ$I}d%N zGX1#Aq*=U2#;kQiI!MU>9~@iB$T`<8VXrzdmtV8xAdd2@$SW8b5@>h~VQIiVj7-r+ z-Z9z1_4{UfD+4f%-6&0%Z!LP#0>e}bgSwLCBJI=*Y>B~5j3j@&m@5rj`pBPCAkfv< zqwDfcYGJq<_FQdZna;!R*IM7U7dk97xH|QUBNRza)k^fX$s9%*91ae|y5WBM# zCK&rCuyKA5*cs)(FIvharNs=ofdA1H}p#yWak~1@Ybmt6p{) z79_<6g|R^q#w)v>U>`}+*I(TS1$7@8Z3H{%#GXhbEt$6prxCBd_q(nW@K`7n4-UEJ)0Hg#$T7g3r&D6)2?lmKXDiraVxU1|2!;ye4oF9 zyaaKN&%`i{eE)U+m)|~auYXS_eKm8|`D0jz?gY{y`w4d^$h$^5n8=KA1#CqAd$i6O z)8j6AWtJ? zbM1_|Up3^3CY&jQ;{%y)!)bq)pq2Yy9>ye|`7(XLM|4H4D_Gtx3%BQQYp~5AFl1p2aQ}ASotakkHGC+7&2*|mvS14r%^*IwTrs=gFQsnA*aNi- z`gyT#si?p(UZ}#m)37M^A?ZDt!RZ*PEJj(LTnIv0{WK()HF<&49-Rji;Gi4r+PyiR zw3Xs-nc$;UyoXk-=XM}QJ)le68k~0*#>K~phu4eSKDrmYWyMasg~sPZ&ww>51BGIC zlrf5m*BH(l#zAaAx3DRX+GTznd=ZPl(UNfXoG4NnjGW@tFbC=KpME~lXAeQn$e|4v z`>g-0$1}nl?kvwY$814hIL_=KZRZQ!19=@Dntt6Kqqj958m85i;OR_46uH}p@ZyS3 zg#SLJ)fM{nx^~B=S+d`6lB2Ia4MC9*-pDOfKv8^prMo671Bsp+jirkm-uTOB0Q^y~>+VNNd?9-s&z+o*TnRsOdRg35FK-mIh}(Y;6OUQ?EGb|K>+ z*sZ+>Mv4c5j1V_y281z}IcqrP?+9fgsQQW_7WR=5Bhg@LO~FT^S|aG^EZ2`_PASiH zvmsV)0St~f+7J}PU|NyPI7TjX|FR#r| zgrih1@Myb``AA2s#r8-*Ra;5JNiF=eMtE~}(vwim-8lSJ+1uf_`Eq=lGE?LGbTI51 z`{E`vURSmcw4ClW4wxY1+C&h*&2`kt2GZzKE76VKOp27x0_BB*y;nhG4a!>Cr`m%{C5)t`@xrf76>PoE@m_y@(dl{l?ok4_=Swb@eglCs z#U4pw%$-X^%;F-gtRKZavit;O$4s)R&0F#8g?HvUvTAqr{8{$YnMOQ=^Cj(O`%$_A zf2~jz%=Zf|X4(!N^LvnlY#VuUS=1}3IO+maM2QXdUhl@l?}2aM(WUixZqNP&MZ8&| zX1&^d%v8AA0%4_qtqgJ~rS0@{bHc`&2G|6!0myQoo&@En&0i?sRjtlw?2W+!$$S!0 z%<#lFtBqWReO+{YvV{7C^WQRhh#0_G>BE8V$Mp;UGhMM1l!|Ai+7Je=Ex0{0jT4&7 z*E-vMWM|X@CG~hOH%HjZ%RPV2wjU4GrxfS`GXB5uf}l#WZ`N7?+S|R{@A2%8;UFtV z`8GGOKjaWq<}Ci=np~PW9O}laV({p9iwPsI=m&+|(~(cP=)*jpdkbHWksp-4NKT#h z9e1cUb$GV9%@g6>kMrq0VG^k;u~N?# zC*R+Zd}A+=QvOap4l<9A*?^T|8GQBz-AHIUK-4wCJqN6qHkqi+a7hxzARVcTqk*E5rZ?$6Kvt=Pr+^8v% zPw$>X2X7DI0T8;zp5Y&$Mc!Uc(ThLEj+bLNf{^}zlaS~rP2mO7SZnrMUY3L^Rt->F zx6RX<1r0-BkJ}M8!~g4mRbLo=DHp-xk+`J}x$Ruct4mIewe|ggrN_7N`j8oXpQHEK zt`Q{vG*4F9Z~HMj&tM~;!ni1&Q?bRAfA#z3 zulw+22RLx$brqRXP0YkFE=F_`m|_Z|RIfiyG59ODoxtHHbbuG*=R^|u&nyR#71@pG zW;O<8JnyJ=PxS0Kr=HKZ>-WsY}e zGu(Q8#@hpg*;U$nk9aFqjJ?9r#}l3`^65!wjX@@0`EU|^rao8%Bz5YlL-bMn6U__b z^SOJcy4E~{dpexw`O7lGT4S3B zXF`j;JM|H4LOu~J$M(g5*5a3!Zy4@<8|A$B2ij4tgh4|1nodG0B==hUTfiN|$Pcf( zK5w5%Hs6h7_>JS%1Ev8=?Cj6+H)rg)3xD`eeZb0{cOMKNF5Dk^h{>>}~jzeVknPATng|&~OXUqWabV8+3j$50aMcjVfPx>kr>-16q3UlbBZ=<4-8UyZI9P z)o!7-d0nT7OyM>~^14Ss!mTn?4K3(>qVtpmCFYOLJvRv6MCjE*HPF^EeWMBh_XiMB zh{}mJjDtD|-)0Rrk#|^?oGL{rTi7FK0XwdR92O?-{A%&yi70^k1ZYG4OH-fSTl~+# zl(#Q&&K+03#c%PqxmMI8_tIy9AJiaJu@Kb`Z9h!(zE0eRh#%*c=rg2+Of z;kjQuAGkg(b!GZANUw|v2HuDnksn6>_;4V2c#*n;kDNO|&{H#Ka0vfj04NyO=ivV! zqq7?U++lS3cO-kT#mI~vRVLY0oOQo4$%c^`-Lp*c?`dSRjTt@A$ZWAOqk9{fUFnk! zBl9o&2PIIzFHyngsr>7y{Obv60Z5B3sKsA4m#20>E7}i^=%Mvqfmt3ss@`i0W;y)b z4T~Nl-YCaF>wmscuGvi6%X%(sJa%^yZX*e=EjhgAR{vU*2hw=DQsE51_4cwJ5$ZQo z5TZB;)&*kMHX*}F7y%>)hicdXgZa(FvY0>VcXzgsQ26Hdq(bkOtOAcn zGb3l(Fv&R6fglg(wfeYMkI%(@v#osGH-fr=kQG zO*D{JQ(G+es%{47%3Kp}`QN(o@i5?w!OIL0E=NEGm{ z*;3cEQf-IJkZ zde|$3awF~;_*aFZ6seF`*G%924QdbtKFDraAW1s-?$pd)OQOgVA^3^-hjvXL;FWIK zAN|MkL_=3{D;dKrIG;hP54(0J=QF#LA%E*dt_|FB19?yAlw|3r@$;bZ=dwHJ*$k=5 zf#ezE`sK>)ugVAecz0`q=NY^i9x8GWh256$)=&F#5`M2bQv9ZP(tXOEk9t%2>>@66 zlp&I{fM4t>DK42l_iA6_K4YdRV~ef?>#9U_Roe3U?;e?H@Qgz zXVHQ}iZe-T8BjD`wvz?jj&I~Mp=3zk$u}Z6&Zbl-G`7ujD73e=lqg#I+ewRV$rIAl zDEejFOON84ZYf2IzFNZ*@;33D>Lfy79p)8LFvLUZAWw)f`1EU<&yj1xtL{;I=Ae)R z8jlfD0mT>*>e7G^BqkXeAF04ZUo)2d8%o#_F%zgaaJr)41WG7qIiaE-_}ahtgsCu@ zTjugf*85j>g?ze%A}f~>=(SAI61mLg&Y0-^%jEK3!E*Dq;1Kxji)$eAMvBa?D^uM3hc{fY#Ofbi=)Lw`{j*3l;U z7vatLS5n28%`=e=$7Nc1%Mrp#Z^nnv@E4d}mHYik`esfuAmow}H(0g0x=I)Mztf(s&<-NKZ}SY8ltreC z6W)#clc1KXo(rfvK)hVUN1rbF9pu$Gp^6oZFqh~T(nntIi4s>!YU_vi)ERa0=Xr^1 zXFV^0mPA%fJgBbA5`<-nIdTd~J1u`&q6+$X|HZzWp>zQ*)G&754Hs7e21K2?Ax*5< z79t@TBFgAwB7+SrFBqNqx{f}E{9Lit*tu%K+R86%DomWfAqhgqKtYx+zGUiDFAZ4m1i=32J*>xGcJ;0Tlpw0w!!M-O3_0K`|lyc)< zn_$PC3_Gw|cCer|i^uNBobT}5!=Hb_8HNRt7ptuLS2K(6%NvNlCo~yw_T$lyXEtkY znQU#PxEz&LHhq+p#X9U5OUM_~n8~{mua&OQ6tO4CcUGDMbq1kBv^lQUY}FF5ubjig znxzCsBT;@yxWi7ZcNwkoKbbfu0Eu~Yir~KZ3Njp;Grw@l>WcTO^bDlkZe4kVH-cMF z+9EdrYlo2>Puf$I(bsJ6bzBA6crWs!v#E1dp!fu9?}DK~;@JEKcxJ*m2*PW)%t#j* zwyCIUu_&GCz;;}zmR*v2NVGs68|2+Xglr` zogs$e(8Hy6XCR_{_vh<@W=!VbT;mTM6XFN% z+hQFEoZ;RLeDhSe1^mfiZUzr9TnLL;V0<(5PmNKGUD9K((!c5XcwUxYD(8^{)^Cy% zF~Y>F4UweUk`$3<0H1SL%6xj0V{G?Bsdt`z6+VJ!r)0g09z1x*q$%|t|CZj^-U&E@ z*@d&%yrS~5CiVx4U9k5d)+Hqfu(a{e;C6gIxMJcpMNEQGbOuo(5T{qo!5dg9&ZsCV zrX~}a(9fu;O_)Lb#N3w?QEx$xDf_n-nQUv6ADho!>-EKLx$Q#w&g+=9v2HFiyfQ%y z)cFdG6kAowk^%8Jd;&<%!#!AVTiET18|0uc8vk_2 zOUr89lDahh*^0z8cY1p|)BKuS6q}~yxIM*bSwmZrou*@Ui`vt6Sw2>Pn%df^LJdpv z)twH^uyi+63*O))(DYr<@SL);SPuK zxYzGlr#y_=m`wr>b!be~o(z|lGuxcCW1Nr{uegag4SVAjv%B-kD(*Wc$hlJe#RV7< zMcQj~v0Kvn_sRA7mfDkkchC3vmN>>(s~c|)FY*9Zx;iHvwquU^+eHh)Rq$ru zn|Y+5Tdb!TOnB=_QqznwXUK=)*aV<`I|g6hTnCFho5ydV1THPAFYEZ{nfv=60dKfp zO><^Jl}}sB)%r)=|Gtxrhh9jwuE6}fNvrxMI!xX4#~;#v&p~~(xr?}!_PwO*0|HYC z{QnT&90(WX5&GVqd!zhs#WZzuTZ7WLCVzDfAh;3kBkt$! zpeUB5`^_6Ld*^AkkavUbeN0#LGJcaT+#W1Rv$;u@T&wjL*HI%TKC{bH`cp8af0SVG zcfA+!?qN2`uFl-<;{!p^Fp;pl_awgtV}2Lh#{OX3 z*3ut&9>M{MfBs7U?k(`&f6UyK(fhKRXDc^_y>!w$&wgn((ip|~=M;a`JJ%oGv8iy- zf4+u)_Ri^_e{@ddB85%YJ74_Lb|7k|#@En=LK(r_-S13gh^o*9Jb&JC#G2W9XaaWQ z5&eiHY<&Mj?6@TpyR{=fxx<-%UoB5P`5&w4DGhB&+f!$9D;l3>i9J^9Q<{2!<|m$H zKgjWNQkYPv>Tfvft{!0KJMTMIT=sb#WYVT!sfNh2_^inBlqA~5gLIy|1Fy)_B(8Fd zPQ$jw1OSC=DOwIeHEv9^Z*Q{2mu!yO>C?`;l`PEPe~0($3;h4D@c+|KeyAmR@WRP1 zd`hgl!yAgBYNyb4kZ180(Pwc3ffjGCHY(m49xdJ~CN17FE-l_RHZ2x>S{EIJS&Db# zv`~oJ*0?RC#rsf0-2Yl04cy6iI=+=ALNCE>0j1)<16b-__q4qEM#NP7cR)?W+eS{s z+eJ^se+L9rynPf^yk#U++=ixd|NBt}WrV15I^sh#M^?+{$N?lbHn0&)(}g%Wul6yk zYG4^{eh-~DY1N=+s@N5J_90z-Syk~{=Z{Z;fd84hQ-OLS9;N9N4&rCW&Qq_TB<*Vn z$JDdK)kQomu{7mbKV7&p^dP;uK1WUn_gjlJf*<@jb8byMUS?l2`g&S`>;GqWOXc{D zPgww@dSak-dYrTFi0e&rtfDW8AI3;Kuz>B*oo zp7o0<2(_&y80C9*aJg{jb$^;((LbH3R1_(Ah1KK|(MZn@7Vatl3UC~`tZ<+I2$&BX z*>~Au86TGJ2B69KQ~ISmkH?eC`Fcs8_)`jy*TeD#?TBZ8T3x2`=f&Ut`~P?T-~T^2 z`T67$eAe;OtwbE?Y)LHXec>yq;?rz$S(Nkgg4xJ%0!m;5Kg>`U5g&D0PN(rf&rJNM zbnT2%*PTU~P5DRemw9>>|H(a$7lU&yi}-Xk;ddIZ3KsNPSIdkB2J1%-PTUG9SJ!3< zeR8t`aJ*;E-iY6)OYELs9=`%GWf^}Pzk}$co7yZeI-ktECo}KPX5PJH6dR+!n@pGF zp<20mnZ4bfMhW$C6IA>TMY6V~`x!c$3T5L*7t03rjkT#Bqe8;=ja@GfmLd`R#y9qG zJ(AGA=~&LmgX0jt-)mmIiu$Y-+31a|&^;5DP50uf=?{nr=}i*<_e;KCU6*&DM{fp$ z(LQcL#vts(yCY|5U_AHxS9?G4hkw4l{PIV4cjZNI`lZO0?*ISd+@4aHVFA}ja6PWL z#2OSmN-^FJ?Qq=Nh`jq1|)DtaHhZEwTx}PT$L=1V~k8&b&LsrEBlP;7;d&WX= zivnTVY9?MU-1;h46-xhN-I?pVEa4>nnl9kC@pYa}$j7(&)L4Sx;RC+~o-tn%1$Vy+ z5~r0QxPJ<|H74j2%|=bW7y^5B(==(&sQI=!-GZh$*YFD(mOj?FeZ+b_w$twspCb#n zAkH=CFZAN^S5T=eXER-@TQS+5ZOL4F7MN|uwJLvFfb?BW-?Tgusk_D#Nitr9RV*Vp9Euog;F!-pg~}t zI|=$D<~|LMNDq;8XGW`A{OmTDxK&>^>|w`&qen{fw!g^fh{D5Or@mA-Bm?5mAj`uZNG{+`S@$*Z2xpIWn9^auG3MMR@sxT#DA==1egK)QT(JVv2A4uxE|fW zZc$s}uzx%p9L2v5oUa8=-ecq?qB~rLcfJ7eHUIMjCTa)G-$(Rq9}a@M-!v@>6PG!} zL^jdk!if#ZJpAva+g{D1HGcEAa#6VBGh?j?e)+L`=y@gzz*~x+Y%6xMg}BK^8LkjQ zAX~kwpsXXVD__G+-X~vwL#eTB_u;*&jBUvR#-D?5ZT|p^w%y)$o&I=otkFJ>Ai579 z42HkrmjBRqcIW603+lRMB|+uR(@J_;Nq1jKWI*0)A*tc_w2+<_k}f22KiU`4JIJ|y zByh%(^VUy`>1i=-yx*qTtanK^Q;`;8KEYpG@4c77arN{00{;6)w}ci|kKAXsJT9_c zku86DT5C^hEm&)Al4XIxU+=KMo(!v}W#xl;=ViHcGn!uSyBCOR<(#ixynMOu{@?fU z=?yrM3x?@G#mAm>SD$oOIX2c28VhIu?wmTR$H}6HrHs1bWYPUHMVq2zQ7ug7kCb=w zw7Mv7;`eFw1yaU<-E}*5VMK_wf(Cs&6x5Z^C&^rHf z1k1fU>W|-@d?H*GGVFDsLhk?wjp7Hh6t*F(Tyys=JL)^ee{zVS`G?;-vk6uNJ2{x} z#Co$#mK^<_^!%_;jol?E3Ue!;TZ&NVaaA~TgtksqLNy?sL3Y)mqNF=wYJrg)1xzAa z7*~&T5W$}saF`ATJBRw=9vj70<|YRU1=t}-+s!g3b3Fa~J#cnee+i4r40hLzE_0zHOKgO}q`^Pvso{o?IX^xLYc9H$Yq$eha z6K{)#ZId_VdHYDQmRBNBq#Svwe`37aCfDiqXim4xaJp4;(=GFwZj;hR?cf@P?KMmubt-X!t=|Nr%W{9pg)|B2FjHz_*v zd^hkFgG#NUIS+bfnfviMP+wk{Sav}?l>1k!xx03p>A@-gOQOg6f+D(f?Mk@dG|g|) wf<7mDA(KUhV$%?b1JSo~aq%sw5ReGLxBu?m>f4vS7r#XRHz`EjH7|?<09gy6egFUf From 9eecb4084e5dafa67d5cbddf163e3f40fc8c9c91 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sat, 5 Mar 2016 11:27:33 -0400 Subject: [PATCH 14/58] changelog --- debian/changelog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/debian/changelog b/debian/changelog index 3ea3cc1aff..9bd61260f7 100644 --- a/debian/changelog +++ b/debian/changelog @@ -6,6 +6,8 @@ git-annex (6.20160230) UNRELEASED; urgency=medium * Fix shared lock file FD leak. * Fix metadata hook behavior when multiple files are added at once. Thanks, Klaus Ethgen. + * Added dependencies on haskell mountpoints and disk-free-space + libraries, removing FFI code from git-annex. -- Joey Hess Mon, 29 Feb 2016 13:00:30 -0400 From 38d7df337418cf1625d61c95b47484715e8fe9f5 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sat, 5 Mar 2016 11:29:14 -0400 Subject: [PATCH 15/58] add new deps --- debian/control | 2 ++ 1 file changed, 2 insertions(+) diff --git a/debian/control b/debian/control index 25d6d9c924..d2f6e5c64f 100644 --- a/debian/control +++ b/debian/control @@ -72,6 +72,8 @@ Build-Depends: libghc-optparse-applicative-dev (>= 0.11.0), libghc-torrent-dev, libghc-concurrent-output-dev, + libghc-disk-free-space-dev, + libghc-mountpoints-dev, libghc-magic-dev, lsof [linux-any], ikiwiki, From 5f3fa4642e4d0bf80e8afe682956ab806399853c Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sat, 5 Mar 2016 11:32:05 -0400 Subject: [PATCH 16/58] close bug about removed code --- doc/bugs/Utility__47__libdiskfree.c_more_BSD_friendly.mdwn | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/bugs/Utility__47__libdiskfree.c_more_BSD_friendly.mdwn b/doc/bugs/Utility__47__libdiskfree.c_more_BSD_friendly.mdwn index 613e11eae6..51894cac60 100644 --- a/doc/bugs/Utility__47__libdiskfree.c_more_BSD_friendly.mdwn +++ b/doc/bugs/Utility__47__libdiskfree.c_more_BSD_friendly.mdwn @@ -79,3 +79,6 @@ The diff probably needs check, improvement... Not tested this "feature" yet, I got another issue which blocks me for now. +> Well, this code has been removing from git-annex, and it's now using +> . I think that +> library is somewhat more portable. [[done]] From ca18baecdbcf91fa39343e0e9b81d4e9bdd4396f Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sat, 5 Mar 2016 12:32:06 -0400 Subject: [PATCH 17/58] fix windows build more --- Utility/LockPool/Windows.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Utility/LockPool/Windows.hs b/Utility/LockPool/Windows.hs index 0ca3c81164..9f3a0b95cc 100644 --- a/Utility/LockPool/Windows.hs +++ b/Utility/LockPool/Windows.hs @@ -34,7 +34,7 @@ lockShared file = tryMakeLockHandle P.lockPool file - content, a separate LockFile should be used. -} lockExclusive :: LockFile -> IO (Maybe LockHandle) lockExclusive file = tryMakeLockHandle P.lockPool file - (\p f -> P.tryTakeLock f LockExclusive) + (\p f -> P.tryTakeLock p f LockExclusive) (\f -> fmap mk <$> F.lockExclusive f) {- If the initial lock fails, this is a BUSY wait, and does not From e859ebe2b3255e172d292e090bf69df0ad611a42 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sat, 5 Mar 2016 13:57:43 -0400 Subject: [PATCH 18/58] more windows build fixes --- Utility/Touch.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Utility/Touch.hs b/Utility/Touch.hs index 60b9cb928c..dbaf9e588c 100644 --- a/Utility/Touch.hs +++ b/Utility/Touch.hs @@ -43,7 +43,7 @@ import System.PosixCompat newtype TimeSpec = TimeSpec EpochTime {- Noop for Windows -} -touchBoth FilePath -> TimeSpec -> TimeSpec -> Bool -> IO () +touchBoth :: FilePath -> TimeSpec -> TimeSpec -> Bool -> IO () touchBoth _ _ _ _ = return () touch :: FilePath -> TimeSpec -> Bool -> IO () From 112caada868f5c2b60271b58c4639e9ec85bfca8 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sat, 5 Mar 2016 15:08:37 -0400 Subject: [PATCH 19/58] another windows build fix --- Utility/Touch.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Utility/Touch.hs b/Utility/Touch.hs index dbaf9e588c..62acea02ae 100644 --- a/Utility/Touch.hs +++ b/Utility/Touch.hs @@ -47,6 +47,6 @@ touchBoth :: FilePath -> TimeSpec -> TimeSpec -> Bool -> IO () touchBoth _ _ _ _ = return () touch :: FilePath -> TimeSpec -> Bool -> IO () -touch _ _ = return () +touch _ _ _ = return () #endif From 35aad6ee7f73a5d7e988dc71eb8d0419306d3fa9 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sat, 5 Mar 2016 15:18:52 -0400 Subject: [PATCH 20/58] fix build with old ghc --- Utility/LockPool/LockHandle.hs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Utility/LockPool/LockHandle.hs b/Utility/LockPool/LockHandle.hs index 34446ff52e..41b110aeea 100644 --- a/Utility/LockPool/LockHandle.hs +++ b/Utility/LockPool/LockHandle.hs @@ -23,6 +23,8 @@ import Utility.LockPool.STM (LockFile) import Control.Concurrent.STM import Control.Exception +import Control.Applicative +import Prelude data LockHandle = LockHandle P.LockHandle FileLockOps From 844e0b3ad9537889b3b9339f1a0720e51bbc39f6 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sat, 5 Mar 2016 16:17:14 -0400 Subject: [PATCH 21/58] add new deps --- stack.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/stack.yaml b/stack.yaml index a7660e02af..4d2efbe56a 100644 --- a/stack.yaml +++ b/stack.yaml @@ -20,3 +20,6 @@ flags: packages: - '.' resolver: lts-5.0 +extra-deps: +- mountpoints-1.0.1 +- disk-free-space-0.1.0.1 From 9ee367a8145ead48e16e6501a4de545d086b6aad Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sat, 5 Mar 2016 16:20:35 -0400 Subject: [PATCH 22/58] switch to lts 5.5 --- stack.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stack.yaml b/stack.yaml index 4d2efbe56a..cb7a573a30 100644 --- a/stack.yaml +++ b/stack.yaml @@ -19,7 +19,7 @@ flags: ekg: false packages: - '.' -resolver: lts-5.0 +resolver: lts-5.5 extra-deps: - mountpoints-1.0.1 - disk-free-space-0.1.0.1 From 404ad86ef9180cd81e73d97dd5f16810d4a07871 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sat, 5 Mar 2016 16:57:37 -0400 Subject: [PATCH 23/58] allow linuxstandalone to be used with stack built binary --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index f94ca9fc78..cee4ee02ef 100644 --- a/Makefile +++ b/Makefile @@ -135,7 +135,7 @@ linuxstandalone-nobuild: Build/Standalone Build/LinuxMkLibs sed -i -e 's/^GIT_ANNEX_PACKAGE_INSTALL=/GIT_ANNEX_PACKAGE_INSTALL=$(GIT_ANNEX_PACKAGE_INSTALL)/' "$(LINUXSTANDALONE_DEST)/runshell" install -d "$(LINUXSTANDALONE_DEST)/bin" - cp dist/build/git-annex/git-annex "$(LINUXSTANDALONE_DEST)/bin/" + cp git-annex "$(LINUXSTANDALONE_DEST)/bin/" strip "$(LINUXSTANDALONE_DEST)/bin/git-annex" ln -sf git-annex "$(LINUXSTANDALONE_DEST)/bin/git-annex-shell" zcat standalone/licences.gz > $(LINUXSTANDALONE_DEST)/LICENSE From 59bad9681b70fc29077ac9ad9cf2bb2445658b56 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sat, 5 Mar 2016 17:16:46 -0400 Subject: [PATCH 24/58] i386ancient build switched to stack, has more flags enabled --- ...nux_standalone_builds:_no_longer_usable_on_CentOS_6.5.mdwn | 4 ++++ doc/install/Linux_standalone.mdwn | 3 +-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/doc/bugs/Set_some_reasonable_requirements_lower-bound_for_linux_standalone_builds:_no_longer_usable_on_CentOS_6.5.mdwn b/doc/bugs/Set_some_reasonable_requirements_lower-bound_for_linux_standalone_builds:_no_longer_usable_on_CentOS_6.5.mdwn index 5f7166ed3c..f2ff387026 100644 --- a/doc/bugs/Set_some_reasonable_requirements_lower-bound_for_linux_standalone_builds:_no_longer_usable_on_CentOS_6.5.mdwn +++ b/doc/bugs/Set_some_reasonable_requirements_lower-bound_for_linux_standalone_builds:_no_longer_usable_on_CentOS_6.5.mdwn @@ -2,3 +2,7 @@ standalone builds leap forward a bit too fast in terms of their demand on modern kernel. Up until a month ago, standalone build worked at least on CentOS 6.5 with 2.6.32-431.11.2.el6.x86_64 (although [already didn't on ancient but still in use RHEL5 with 2.6.18](https://github.com/datalad/datalad/issues/176#issuecomment-114612365)). Current build from 20150916 doesn't work on CentOS 6.5 any longer. No matter how much I like people to use more recent releases of their distributions, it is infeasible to demand people to do that. It would be great if standalone builds were carried out on some elder kernel/libc environment to make git-annex standalone builds usable there. +> [[done]]; the ancient build provides this. It's now build with stack, so +> it gets most features enabled. (Except xmpp, notably.) This does mean +> it will only get library security fixes once git-annex's stack.yaml +> is updated to require a new version of the affected library. --[[Joey]] diff --git a/doc/install/Linux_standalone.mdwn b/doc/install/Linux_standalone.mdwn index 4d0a1c096d..223c8189b3 100644 --- a/doc/install/Linux_standalone.mdwn +++ b/doc/install/Linux_standalone.mdwn @@ -26,8 +26,7 @@ linux systems. * [[forum_thread|forum/new_linux_arm_tarball_build]] The build for ancient kernels is for use with Linux kernel versions -such as 2.6.32. It is missing some features, like SHA3 support and -the webapp. It will work on both 32 and 64 bit systems. +such as 2.6.32. It will work on both 32 and 64 bit systems. ## autobuilds From 8a546436182afec9dfa0c6b4372bcc3ca6a0c013 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sat, 5 Mar 2016 17:33:52 -0400 Subject: [PATCH 25/58] update flag list --- doc/install/fromsource.mdwn | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/install/fromsource.mdwn b/doc/install/fromsource.mdwn index 85df281943..ef8482edd7 100644 --- a/doc/install/fromsource.mdwn +++ b/doc/install/fromsource.mdwn @@ -73,8 +73,8 @@ to be broken from time to time. Inside the source tree, run: - cabal install -j -f"-assistant -webapp -webdav -pairing -xmpp -dns" --only-dependencies - cabal configure -f"-assistant -webapp -webdav -pairing -xmpp -dns" + cabal install -j -f"-assistant -webapp -webdav -pairing -xmpp -dns -dbus -magicmime" --only-dependencies + cabal configure -f"-assistant -webapp -webdav -pairing -xmpp -dns -dbus -magicmime" cabal build -j PATH=$HOME/bin:$PATH cabal install --bindir=$HOME/bin @@ -98,4 +98,5 @@ Once the C libraries are installed, run inside the source tree: When building with cabal, you can optionally enable the [[EKG monitoring interface|ekg]]. This is great for debugging resource -usage problems. Just pass `-f+EKG` to `cabal configure` +usage problems, but not for general-purpose builds. +Just pass `-f+EKG` to `cabal configure` From 78fa865721d49c5382e495c71f58a8e80b6db071 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sun, 6 Mar 2016 12:45:57 -0400 Subject: [PATCH 26/58] dropkey: Add --batch. --- Command/DropKey.hs | 39 ++++++++++++++++++++++++++++---------- debian/changelog | 1 + doc/git-annex-dropkey.mdwn | 7 +++++++ 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/Command/DropKey.hs b/Command/DropKey.hs index 60d7d5fc75..71993acbb2 100644 --- a/Command/DropKey.hs +++ b/Command/DropKey.hs @@ -1,6 +1,6 @@ {- git-annex command - - - Copyright 2010 Joey Hess + - Copyright 2010,2016 Joey Hess - - Licensed under the GNU GPL version 3 or higher. -} @@ -13,26 +13,45 @@ import Logs.Location import Annex.Content cmd :: Command -cmd = noCommit $ +cmd = noCommit $ command "dropkey" SectionPlumbing "drops annexed content for specified keys" (paramRepeating paramKey) - (withParams seek) + (seek <$$> optParser) -seek :: CmdParams -> CommandSeek -seek = withKeys start +data DropKeyOptions = DropKeyOptions + { toDrop :: [String] + , batchOption :: BatchMode + } -start :: Key -> CommandStart -start key = stopUnless (inAnnex key) $ do +optParser :: CmdParamsDesc -> Parser DropKeyOptions +optParser desc = DropKeyOptions + <$> cmdParams desc + <*> parseBatchOption + +seek :: DropKeyOptions -> CommandSeek +seek o = do unlessM (Annex.getState Annex.force) $ error "dropkey can cause data loss; use --force if you're sure you want to do this" + withKeys start (toDrop o) + case batchOption o of + Batch -> batchInput parsekey $ batchCommandAction . start + NoBatch -> noop + where + parsekey = maybe (Left "bad key") Right . file2key + +start :: Key -> CommandStart +start key = do showStart' "dropkey" key Nothing next $ perform key perform :: Key -> CommandPerform -perform key = lockContentForRemoval key $ \contentlock -> do - removeAnnex contentlock - next $ cleanup key +perform key = ifM (inAnnex key) + ( lockContentForRemoval key $ \contentlock -> do + removeAnnex contentlock + next $ cleanup key + , next $ return True + ) cleanup :: Key -> CommandCleanup cleanup key = do diff --git a/debian/changelog b/debian/changelog index 9bd61260f7..59ac9a51be 100644 --- a/debian/changelog +++ b/debian/changelog @@ -8,6 +8,7 @@ git-annex (6.20160230) UNRELEASED; urgency=medium Thanks, Klaus Ethgen. * Added dependencies on haskell mountpoints and disk-free-space libraries, removing FFI code from git-annex. + * dropkey: Add --batch. -- Joey Hess Mon, 29 Feb 2016 13:00:30 -0400 diff --git a/doc/git-annex-dropkey.mdwn b/doc/git-annex-dropkey.mdwn index 0db29f9009..03f03ec4e6 100644 --- a/doc/git-annex-dropkey.mdwn +++ b/doc/git-annex-dropkey.mdwn @@ -17,6 +17,13 @@ to have a file in the git repository pointing at them. Warning: This command does not check that enough other copies of the content exist; using it can easily result in data loss. +# OPTIONS + +* `--batch` + + Enables batch mode, in which lines containing keys to drop are read from + stdin. + # SEE ALSO [[git-annex]](1) From acf74ae945e62ea1aacaa139d6bf0c59a64d2f27 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sun, 6 Mar 2016 12:56:39 -0400 Subject: [PATCH 27/58] improve json when showStart' is given only a key Before, the json contained file:key; change that to key: If a file and a key are given, inclue both file: and key: --- Messages.hs | 8 ++++---- Messages/JSON.hs | 15 ++++++++++----- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/Messages.hs b/Messages.hs index 8d8f916cea..57541cfc05 100644 --- a/Messages.hs +++ b/Messages.hs @@ -54,12 +54,12 @@ import Types.Key import qualified Annex showStart :: String -> FilePath -> Annex () -showStart command file = outputMessage (JSON.start command $ Just file) $ +showStart command file = outputMessage (JSON.start command (Just file) Nothing) $ command ++ " " ++ file ++ " " showStart' :: String -> Key -> Maybe FilePath -> Annex () -showStart' command key afile = showStart command $ - fromMaybe (key2file key) afile +showStart' command key afile = outputMessage (JSON.start command afile (Just key)) $ + command ++ " " ++ fromMaybe (key2file key) afile ++ " " showNote :: String -> Annex () showNote s = outputMessage (JSON.note s) $ "(" ++ s ++ ") " @@ -166,7 +166,7 @@ showFullJSON v = withOutputType $ liftIO . go -} showCustom :: String -> Annex Bool -> Annex () showCustom command a = do - outputMessage (JSON.start command Nothing) "" + outputMessage (JSON.start command Nothing Nothing) "" r <- a outputMessage (JSON.end r) "" diff --git a/Messages/JSON.hs b/Messages/JSON.hs index be3dbbc585..fa829a76ce 100644 --- a/Messages/JSON.hs +++ b/Messages/JSON.hs @@ -17,13 +17,18 @@ module Messages.JSON ( import Text.JSON import qualified Utility.JSONStream as Stream +import Types.Key +import Data.Maybe -start :: String -> Maybe String -> IO () -start command file = - putStr $ Stream.start $ ("command", command) : filepart file +start :: String -> Maybe FilePath -> Maybe Key -> IO () +start command file key = putStr $ Stream.start $ catMaybes + [ part "command" (Just command) + , part "file" file + , part "key" (fmap key2file key) + ] where - filepart Nothing = [] - filepart (Just f) = [("file", f)] + part _ Nothing = Nothing + part l (Just v) = Just (l, v) end :: Bool -> IO () end b = putStr $ Stream.add [("success", b)] ++ Stream.end From a07fd19ce9fb507187ec983fdabd888d34c4a0f2 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sun, 6 Mar 2016 12:58:36 -0400 Subject: [PATCH 28/58] dropkey --json --- Command/DropKey.hs | 2 +- debian/changelog | 2 +- doc/git-annex-dropkey.mdwn | 5 +++++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Command/DropKey.hs b/Command/DropKey.hs index 71993acbb2..15d5403a8f 100644 --- a/Command/DropKey.hs +++ b/Command/DropKey.hs @@ -13,7 +13,7 @@ import Logs.Location import Annex.Content cmd :: Command -cmd = noCommit $ +cmd = noCommit $ withGlobalOptions [jsonOption] $ command "dropkey" SectionPlumbing "drops annexed content for specified keys" (paramRepeating paramKey) diff --git a/debian/changelog b/debian/changelog index 59ac9a51be..671ce95045 100644 --- a/debian/changelog +++ b/debian/changelog @@ -8,7 +8,7 @@ git-annex (6.20160230) UNRELEASED; urgency=medium Thanks, Klaus Ethgen. * Added dependencies on haskell mountpoints and disk-free-space libraries, removing FFI code from git-annex. - * dropkey: Add --batch. + * dropkey: Add --batch and --json. -- Joey Hess Mon, 29 Feb 2016 13:00:30 -0400 diff --git a/doc/git-annex-dropkey.mdwn b/doc/git-annex-dropkey.mdwn index 03f03ec4e6..0107ab5385 100644 --- a/doc/git-annex-dropkey.mdwn +++ b/doc/git-annex-dropkey.mdwn @@ -24,6 +24,11 @@ exist; using it can easily result in data loss. Enables batch mode, in which lines containing keys to drop are read from stdin. +* `--json` + + Enable JSON output. This is intended to be parsed by programs that use + git-annex. Each line of output is a JSON object. + # SEE ALSO [[git-annex]](1) From 9a8cdc3652980ae6ac67969013791df2881e981a Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sun, 6 Mar 2016 20:07:38 -0400 Subject: [PATCH 29/58] merge from propellor --- Utility/Process.hs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Utility/Process.hs b/Utility/Process.hs index e12b9700ec..ed02f49e51 100644 --- a/Utility/Process.hs +++ b/Utility/Process.hs @@ -18,6 +18,7 @@ module Utility.Process ( readProcessEnv, writeReadProcessEnv, forceSuccessProcess, + forceSuccessProcess', checkSuccessProcess, ignoreFailureProcess, createProcessSuccess, @@ -129,12 +130,12 @@ writeReadProcessEnv cmd args environ writestdin adjusthandle = do -- | Waits for a ProcessHandle, and throws an IOError if the process -- did not exit successfully. forceSuccessProcess :: CreateProcess -> ProcessHandle -> IO () -forceSuccessProcess p pid = do - code <- waitForProcess pid - case code of - ExitSuccess -> return () - ExitFailure n -> ioError $ userError $ - showCmd p ++ " exited " ++ show n +forceSuccessProcess p pid = waitForProcess pid >>= forceSuccessProcess' p + +forceSuccessProcess' :: CreateProcess -> ExitCode -> IO () +forceSuccessProcess' _ ExitSuccess = return () +forceSuccessProcess' p (ExitFailure n) = fail $ + showCmd p ++ " exited " ++ show n -- | Waits for a ProcessHandle and returns True if it exited successfully. -- Note that using this with createProcessChecked will throw away From ab5f7b05f5bd54c50585c50c9f8d3b17d560f994 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Mon, 7 Mar 2016 12:55:01 -0400 Subject: [PATCH 30/58] Fix OSX dmg to include libraries needed by bundled gpg, lost in last release. --- Build/OSXMkLibs.hs | 7 ++++++- debian/changelog | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Build/OSXMkLibs.hs b/Build/OSXMkLibs.hs index 80f24a6811..c23f4a3210 100644 --- a/Build/OSXMkLibs.hs +++ b/Build/OSXMkLibs.hs @@ -49,6 +49,10 @@ installLibs appbase replacement_libs libmap = do let fulllib = dropWhile (== '/') lib let dest = appbase fulllib let symdest = appbase shortlib + -- This is a hack; libraries need to be in the same + -- directory as the program, so also link them into the + -- extra directory. + let symdestextra = appbase "extra" shortlib ifM (doesFileExist dest) ( return Nothing , do @@ -56,7 +60,8 @@ installLibs appbase replacement_libs libmap = do putStrLn $ "installing " ++ pathlib ++ " as " ++ shortlib unlessM (boolSystem "cp" [File pathlib, File dest] <&&> boolSystem "chmod" [Param "644", File dest] - <&&> boolSystem "ln" [Param "-s", File fulllib, File symdest]) $ + <&&> boolSystem "ln" [Param "-s", File fulllib, File symdest] + <&&> boolSystem "ln" [Param "-s", File (".." fulllib), File symdestextra]) $ error "library install failed" return $ Just appbase ) diff --git a/debian/changelog b/debian/changelog index 671ce95045..fe8d0cb1ad 100644 --- a/debian/changelog +++ b/debian/changelog @@ -9,6 +9,8 @@ git-annex (6.20160230) UNRELEASED; urgency=medium * Added dependencies on haskell mountpoints and disk-free-space libraries, removing FFI code from git-annex. * dropkey: Add --batch and --json. + * Fix OSX dmg to include libraries needed by bundled gpg, + lost in last release. -- Joey Hess Mon, 29 Feb 2016 13:00:30 -0400 From e8d6dc9527c774da0f25f2c5b1ec864b06cbe116 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Mon, 7 Mar 2016 13:21:47 -0400 Subject: [PATCH 31/58] followup --- ..._cf9f4221695d620dfa768b0216171690._comment | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 doc/bugs/git-annex:_failed_to_lock_content/comment_1_cf9f4221695d620dfa768b0216171690._comment diff --git a/doc/bugs/git-annex:_failed_to_lock_content/comment_1_cf9f4221695d620dfa768b0216171690._comment b/doc/bugs/git-annex:_failed_to_lock_content/comment_1_cf9f4221695d620dfa768b0216171690._comment new file mode 100644 index 0000000000..a6fef26b29 --- /dev/null +++ b/doc/bugs/git-annex:_failed_to_lock_content/comment_1_cf9f4221695d620dfa768b0216171690._comment @@ -0,0 +1,25 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 1""" + date="2016-03-07T16:58:35Z" + content=""" +I replicated this as best I could, and the dropunused succeeded. But my +strace has an extra chmod: + + stat("./annex/objects/02e/a64/SHA256E-s30--b6eac296ebeab4b5593387489571654cd5019d8bb3bc3bc08ac8a41e22bad133/SHA256E-s30--b6eac296ebeab4b5593387489571654cd5019d8bb3bc3bc08ac8a41e22bad133", {st_mode=S_IFREG|0444, st_size=30, ...}) = 0 + stat("./annex/objects/02e/a64/SHA256E-s30--b6eac296ebeab4b5593387489571654cd5019d8bb3bc3bc08ac8a41e22bad133/SHA256E-s30--b6eac296ebeab4b5593387489571654cd5019d8bb3bc3bc08ac8a41e22bad133", {st_mode=S_IFREG|0444, st_size=30, ...}) = 0 + chmod("./annex/objects/02e/a64/SHA256E-s30--b6eac296ebeab4b5593387489571654cd5019d8bb3bc3bc08ac8a41e22bad133/SHA256E-s30--b6eac296ebeab4b5593387489571654cd5019d8bb3bc3bc08ac8a41e22bad133", 0100644) = 0 + open("./annex/objects/02e/a64/SHA256E-s30--b6eac296ebeab4b5593387489571654cd5019d8bb3bc3bc08ac8a41e22bad133/SHA256E-s30--b6eac296ebeab4b5593387489571654cd5019d8bb3bc3bc08ac8a41e22bad133", O_RDWR) = 16 + +So, it kind of looks like it checked the permissions and decided 0444 was good +enough and didn't chmod it to allow write (in order to lock it for removal). + +The only way I can see how that could perhaps happen is if git-anenx thinks +it's in a crippled filesystem that doesn't support chmod. But then the file +shouldn't be locked down like that. I was, though, able to reproduce +that behavior after running `git config annex.crippledfilesystem true` + +So, I need more information: What filesystem is the USB drive formatted with, +and can you run `git config --list` in the git repository on the drive and +paste the output please. +"""]] From d3775e741ea64cfcd124067500a30c9e06c8bcc1 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Mon, 7 Mar 2016 13:24:11 -0400 Subject: [PATCH 32/58] followup --- .../comment_3_f4df42fe943011cc8feb2921a59616e9._comment | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 doc/tips/largefiles/comment_3_f4df42fe943011cc8feb2921a59616e9._comment diff --git a/doc/tips/largefiles/comment_3_f4df42fe943011cc8feb2921a59616e9._comment b/doc/tips/largefiles/comment_3_f4df42fe943011cc8feb2921a59616e9._comment new file mode 100644 index 0000000000..b266607781 --- /dev/null +++ b/doc/tips/largefiles/comment_3_f4df42fe943011cc8feb2921a59616e9._comment @@ -0,0 +1,8 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 3""" + date="2016-03-07T17:23:19Z" + content=""" +The first version to support largefiles in .gitattributes was 6.20160211, +so both the above commenters just have too old a version. +"""]] From 4cef8739bbd80adcf1fb4405cc3c87d93bbc399c Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Mon, 7 Mar 2016 13:26:05 -0400 Subject: [PATCH 33/58] comment --- .../comment_2_c5a8839c53145a3b0d44950096c5180f._comment | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 doc/forum/Undo_git_merge_git-annex/comment_2_c5a8839c53145a3b0d44950096c5180f._comment diff --git a/doc/forum/Undo_git_merge_git-annex/comment_2_c5a8839c53145a3b0d44950096c5180f._comment b/doc/forum/Undo_git_merge_git-annex/comment_2_c5a8839c53145a3b0d44950096c5180f._comment new file mode 100644 index 0000000000..4db2007616 --- /dev/null +++ b/doc/forum/Undo_git_merge_git-annex/comment_2_c5a8839c53145a3b0d44950096c5180f._comment @@ -0,0 +1,9 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 2""" + date="2016-03-07T17:25:08Z" + content=""" +`git reflog` is a handy command to get to know, for getting out of +situations along the lines of "I did $something wrong and want to get back +to a previous version of a branch" +"""]] From 9cff9ff02c7ffaef9cbb87d20cd55a2595f2df7b Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Mon, 7 Mar 2016 15:13:01 -0400 Subject: [PATCH 34/58] response --- ..._8e596cd606935d82bd6604f5c9c500a2._comment | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 doc/forum/How_to_shrink_transfer_repo__63__/comment_2_8e596cd606935d82bd6604f5c9c500a2._comment diff --git a/doc/forum/How_to_shrink_transfer_repo__63__/comment_2_8e596cd606935d82bd6604f5c9c500a2._comment b/doc/forum/How_to_shrink_transfer_repo__63__/comment_2_8e596cd606935d82bd6604f5c9c500a2._comment new file mode 100644 index 0000000000..edccafb1ec --- /dev/null +++ b/doc/forum/How_to_shrink_transfer_repo__63__/comment_2_8e596cd606935d82bd6604f5c9c500a2._comment @@ -0,0 +1,21 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 2""" + date="2016-03-07T17:52:21Z" + content=""" +Normally, files should be dropped from the transfer repository once they +have reached all known client repositories. The drop should be done by +the client repositories, so the transfer repo doesn't need access to the +client repos to verify that they have a copy. + +But your problem is with *unused* files that are hanging around in +the transfer repo. This can happen if a file reaches the transfer repo and +then gets deleted from a client, and so the other clients never download it. + +To clean out those files, run: `git annex dropunused --from astarte --force` + +You need to "use the force" because the unused file is only present in the +transfer repo. If you want to get rid of its content for good, that's fine. +A safer option is to move the unused file to the local repo: `git annex +move --unused --from astarte` +"""]] From 8bed51ae95e8e23537cd0692de706c42108fe432 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Mon, 7 Mar 2016 15:54:27 -0400 Subject: [PATCH 35/58] use clamav to check builds for viruses before adding them Had to workaround various problems in clamscan. Increased its max filesize a lot, because it's too small to check git-annex. Manual unpacking seemed to be needed for dmg and tar.gz. --- Build/DistributionUpdate.hs | 58 ++++++++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/Build/DistributionUpdate.hs b/Build/DistributionUpdate.hs index cdebc99e0c..814927e995 100644 --- a/Build/DistributionUpdate.hs +++ b/Build/DistributionUpdate.hs @@ -13,6 +13,7 @@ import Types.Distribution import Build.Version (getChangelogVersion, Version) import Utility.UserInfo import Utility.Url +import Utility.Tmp import qualified Git.Construct import qualified Annex import Annex.Content @@ -56,7 +57,8 @@ main = do state <- Annex.new =<< Git.Construct.fromPath "." Annex.eval state (makeinfos updated version) --- Download a build from the autobuilder, and return its version. +-- Download a build from the autobuilder, virus check it, and return its +-- version. -- It's very important that the version matches the build, otherwise -- auto-upgrades can loop reatedly. So, check build-version before -- and after downloading the file. @@ -72,18 +74,21 @@ getbuild repodir (url, f) = do putStrLn $ "*** " ++ s return Nothing ifM (download url tmp def) - ( do - bv2 <- getbv - case bv2 of - Nothing -> oops $ "no build-version file for " ++ url - (Just v) - | bv2 == bv1 -> do - nukeFile dest - renameFile tmp dest - -- remove git rev part of version - let v' = takeWhile (/= '-') v - return $ Just (f, v') - | otherwise -> oops $ "build version changed while downloading " ++ url ++ " " ++ show (bv1, bv2) + ( ifM (liftIO $ virusFree tmp) + ( do + bv2 <- getbv + case bv2 of + Nothing -> oops $ "no build-version file for " ++ url + (Just v) + | bv2 == bv1 -> do + nukeFile dest + renameFile tmp dest + -- remove git rev part of version + let v' = takeWhile (/= '-') v + return $ Just (f, v') + | otherwise -> oops $ "build version changed while downloading " ++ url ++ " " ++ show (bv1, bv2) + , oops $ "VIRUS detected in " ++ url + ) , oops $ "failed to download " ++ url ) where @@ -170,3 +175,30 @@ signFile f = do ] liftIO $ rename (f ++ ".asc") (f ++ ".sig") void $ inRepo $ runBool [Param "add", File (f ++ ".sig")] + +-- clamscan should handle unpacking archives, but did not in my +-- testing, so do it manually. +virusFree :: FilePath -> IO Bool +virusFree f + | ".tar.gz" `isSuffixOf` f = unpack $ \tmpdir -> + boolSystem "tar" [ Param "xf", File f, Param "-C", File tmpdir ] + | ".dmg" `isSuffixOf` f = unpack $ \tmpdir -> do + -- 7z can extract partitions from a dmg, and then + -- run on partitions can extract their files + unhfs tmpdir f + parts <- filter (".hfs" `isSuffixOf`) <$> getDirectoryContents tmpdir + forM_ parts $ unhfs tmpdir + return True + | otherwise = clamscan f + where + clamscan f' = boolSystem "clamscan" + [ Param "--no-summary" + , Param "-r" + , Param f' + ] + unpack unpacker = withTmpDir "clamscan" $ \tmpdir -> do + unlessM (unpacker tmpdir) $ + error $ "Failed to unpack " ++ f ++ " for virus scan" + clamscan tmpdir + unhfs dest f' = unlessM (boolSystem "7z" [ Param "x", Param ("-o" ++ dest), File f' ]) $ + error $ "Failed extracting hfs " ++ f' From 951857d31fb96531c2bffd5fa0fcc5df348d09c3 Mon Sep 17 00:00:00 2001 From: Horus Date: Mon, 7 Mar 2016 20:11:03 +0000 Subject: [PATCH 36/58] Added a comment --- .../comment_3_c536a946b717e9bdcb883b58cd0336ae._comment | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 doc/forum/How_to_shrink_transfer_repo__63__/comment_3_c536a946b717e9bdcb883b58cd0336ae._comment diff --git a/doc/forum/How_to_shrink_transfer_repo__63__/comment_3_c536a946b717e9bdcb883b58cd0336ae._comment b/doc/forum/How_to_shrink_transfer_repo__63__/comment_3_c536a946b717e9bdcb883b58cd0336ae._comment new file mode 100644 index 0000000000..4d0cee3318 --- /dev/null +++ b/doc/forum/How_to_shrink_transfer_repo__63__/comment_3_c536a946b717e9bdcb883b58cd0336ae._comment @@ -0,0 +1,7 @@ +[[!comment format=mdwn + username="Horus" + subject="comment 3" + date="2016-03-07T20:11:03Z" + content=""" +Thanks, that worked! +"""]] From 3454b8bc332ca1aad84ca34d3635e12aedeac499 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Mon, 7 Mar 2016 16:24:39 -0400 Subject: [PATCH 37/58] devblog --- doc/devblog/day_371__catching_up.mdwn | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 doc/devblog/day_371__catching_up.mdwn diff --git a/doc/devblog/day_371__catching_up.mdwn b/doc/devblog/day_371__catching_up.mdwn new file mode 100644 index 0000000000..02cdf8e7b5 --- /dev/null +++ b/doc/devblog/day_371__catching_up.mdwn @@ -0,0 +1,21 @@ +Over the weekend, I converted the linux "ancient" autobuilder to use stack. +This makes it easier to get all the recent versions of all the haskell +dependencies installed there. + +Also, merged my no-ffi branch, removing some library code from git-annex +and adding new dependencies. It's good to remove code. + +Today, fixed the OSX dmg file -- its bundled gpg was broken. I pushed out a +new version of the OSX dmg file with the fix. + +With the recent incident in mind of malware inserted into the Transmission +dmg, I've added a virus scan step to the release process +for all the git-annex images. This way, we'll notice if an autobuilder +gets a virus. + +Also caught up on some backlog, although the remaining backlog is a little +larger than I'd like at 135 messages. + +Hope to work some more on adjusted branches this week. A few mornings ago, +I had what may be a key insight about how to reverse adjustments when +propigating changes back from the adjusted branch. From 6623b557eda337ded02819749c6f03fc138a30b8 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Tue, 8 Mar 2016 02:45:10 -0400 Subject: [PATCH 38/58] build without disk-free-space on android --- Utility/DiskFree.hs | 15 +++++++++++++++ git-annex.cabal | 6 ++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/Utility/DiskFree.hs b/Utility/DiskFree.hs index fe3a4577c1..be4e823558 100644 --- a/Utility/DiskFree.hs +++ b/Utility/DiskFree.hs @@ -6,12 +6,15 @@ -} {-# OPTIONS_GHC -fno-warn-tabs #-} +{-# LANGUAGE CPP #-} module Utility.DiskFree ( getDiskFree, getDiskSize ) where +#ifndef __ANDROID__ + import System.DiskSpace import Utility.Applicative import Utility.Exception @@ -21,3 +24,15 @@ getDiskFree = catchMaybeIO . getAvailSpace getDiskSize :: FilePath -> IO (Maybe Integer) getDiskSize = fmap diskTotal <$$> catchMaybeIO . getDiskUsage + +#else + +#warning Building without disk free space checking support + +getDiskFree :: FilePath -> IO (Maybe Integer) +getDiskFree _ = return Nothing + +getDiskSize :: FilePath -> IO (Maybe Integer) +getDiskSize _ = return Nothing + +#endif diff --git a/git-annex.cabal b/git-annex.cabal index dcb038d93f..9630948b16 100644 --- a/git-annex.cabal +++ b/git-annex.cabal @@ -111,8 +111,7 @@ Executable git-annex esqueleto, persistent-sqlite, persistent, persistent-template, aeson, feed, - regex-tdfa, - disk-free-space + regex-tdfa CC-Options: -Wall GHC-Options: -Wall -fno-warn-tabs Extensions: PackageImports @@ -193,6 +192,9 @@ Executable git-annex if flag(Android) Build-Depends: data-endian CPP-Options: -D__ANDROID__ -DANDROID_SPLICES -D__NO_TH__ + else + Build-Depends: disk-free-space + if flag(AndroidSplice) CPP-Options: -DANDROID_SPLICES From 05b4d9cc98410e20663de1e933652c1df9059a2a Mon Sep 17 00:00:00 2001 From: "ellis@9dd4c3615b5ff78a457c5832488610886fd6b255" Date: Tue, 8 Mar 2016 19:26:03 +0000 Subject: [PATCH 39/58] Added a comment --- ..._a22011e4b68005c87c4bf9167c22a13f._comment | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 doc/bugs/git-annex:_failed_to_lock_content/comment_2_a22011e4b68005c87c4bf9167c22a13f._comment diff --git a/doc/bugs/git-annex:_failed_to_lock_content/comment_2_a22011e4b68005c87c4bf9167c22a13f._comment b/doc/bugs/git-annex:_failed_to_lock_content/comment_2_a22011e4b68005c87c4bf9167c22a13f._comment new file mode 100644 index 0000000000..b71f04a55e --- /dev/null +++ b/doc/bugs/git-annex:_failed_to_lock_content/comment_2_a22011e4b68005c87c4bf9167c22a13f._comment @@ -0,0 +1,31 @@ +[[!comment format=mdwn + username="ellis@9dd4c3615b5ff78a457c5832488610886fd6b255" + nickname="ellis" + subject="comment 2" + date="2016-03-08T19:26:03Z" + content=""" +Thanks Joey, here's the output from `git config --list`: + + color.diff=auto + color.status=auto + color.branch=auto + push.default=simple + core.precomposeunicode=true + credential.helper=/usr/share/doc/git/contrib/credential/gnome-keyring/git-credential-gnome-keyring + core.repositoryformatversion=0 + core.filemode=false + core.bare=true + core.symlinks=false + core.ignorecase=true + core.fsyncobjectfiles=true + annex.uuid=a8ed0f4a-47c9-4289-947d-2f4650e9ede6 + annex.sshcaching=false + annex.crippledfilesystem=true + annex.version=6 + remote.lorax.url=../../../../../mnt/taiji07/taiji-lib + remote.lorax.fetch=+refs/heads/*:refs/remotes/lorax/* + remote.lorax.annex-uuid=9ea9a021-e3c6-4d55-a118-f3f55387ef40 + filter.annex.smudge=git-annex smudge %f + filter.annex.clean=git-annex smudge --clean %f + +"""]] From 70bf11d3d0905c88852cc7d3ddd35b52514076f4 Mon Sep 17 00:00:00 2001 From: ellis Date: Tue, 8 Mar 2016 19:52:21 +0000 Subject: [PATCH 40/58] Added a comment --- .../comment_3_4d58bfb2ba40e280cf9bcb8a054757f6._comment | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 doc/bugs/git-annex:_failed_to_lock_content/comment_3_4d58bfb2ba40e280cf9bcb8a054757f6._comment diff --git a/doc/bugs/git-annex:_failed_to_lock_content/comment_3_4d58bfb2ba40e280cf9bcb8a054757f6._comment b/doc/bugs/git-annex:_failed_to_lock_content/comment_3_4d58bfb2ba40e280cf9bcb8a054757f6._comment new file mode 100644 index 0000000000..fd50fb0287 --- /dev/null +++ b/doc/bugs/git-annex:_failed_to_lock_content/comment_3_4d58bfb2ba40e280cf9bcb8a054757f6._comment @@ -0,0 +1,9 @@ +[[!comment format=mdwn + username="ellis" + subject="comment 3" + date="2016-03-08T19:52:21Z" + content=""" +And the file system is VFAT: + + /dev/sde1 on /media/ellis/USB04 type vfat (rw,nosuid,nodev,relatime,uid=1000,gid=1000,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,showexec,utf8,flush,errors=remount-ro,uhelper=udisks2) +"""]] From 01f0dfc4ff6f4a9525a725597ae21f733d41473e Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Tue, 8 Mar 2016 16:42:43 -0400 Subject: [PATCH 41/58] followup --- ...t_4_431885c1487035415acbad59b021a548._comment | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 doc/bugs/git-annex:_failed_to_lock_content/comment_4_431885c1487035415acbad59b021a548._comment diff --git a/doc/bugs/git-annex:_failed_to_lock_content/comment_4_431885c1487035415acbad59b021a548._comment b/doc/bugs/git-annex:_failed_to_lock_content/comment_4_431885c1487035415acbad59b021a548._comment new file mode 100644 index 0000000000..4c29c33e25 --- /dev/null +++ b/doc/bugs/git-annex:_failed_to_lock_content/comment_4_431885c1487035415acbad59b021a548._comment @@ -0,0 +1,16 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 4""" + date="2016-03-08T20:38:25Z" + content=""" +Thanks, that's consistent with my analysis. + +The only thing I don't understand is how a file on a vfat filesystem can +have mode 444. When I make a vfat filesystem and mount it on linux, +chmod doesn't change the mode of files at all; they're hardcoded at 755. + +Is your drive mounted with any interesting mount options? Paste the output +from `mount` for the drive. + +Can you chmod the file to have some mode other than 444? +"""]] From 5a3bc8baf82e8cb0321b79b759e8956a41858848 Mon Sep 17 00:00:00 2001 From: "https://me.yahoo.com/a/EbvxpTI_xP9Aod7Mg4cwGhgjrCrdM5s-#7c0f4" Date: Tue, 8 Mar 2016 21:01:06 +0000 Subject: [PATCH 42/58] --- ...me_tests_fail_while_running_under_NFS.mdwn | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 doc/bugs/some_tests_fail_while_running_under_NFS.mdwn diff --git a/doc/bugs/some_tests_fail_while_running_under_NFS.mdwn b/doc/bugs/some_tests_fail_while_running_under_NFS.mdwn new file mode 100644 index 0000000000..2e87ff8a5b --- /dev/null +++ b/doc/bugs/some_tests_fail_while_running_under_NFS.mdwn @@ -0,0 +1,54 @@ +### Please describe the problem. + +4 out of 269 tests failed (4468.00s) + +hard to assess how critical they are... + +### What steps will reproduce the problem? + +run git annex test + +### What version of git-annex are you using? On what operating system? + +6.20160307+gitgb095561-1~ndall+1 + +### Please provide any additional information below. + +[Full log](http://www.onerussian.com/tmp/git-annex-tests-6.20160307+gitgb095561-1~ndall+1.log) + +[[!format sh """ +smaug:/mnt/nfs/scrap/datalad/test_annex +$> grep -B5 FAIL git-annex-tests-6.20160307+gitgb095561-1~ndall+1.log + crypto: OK (50.57s) + preferred content: OK (20.36s) + add subdirs: OK (8.97s) + addurl: .t/tmprepo73/.git/annex/keys: removeDirectoryRecursive: unsatisfied constraints (Directory not empty) +sleeping 10 seconds and will retry directory cleanup +FAIL +-- + 293ed4c..c16b350 git-annex -> synced/git-annex + dd272eb..ffe1721 master -> synced/master +OK (11.64s) + addurl: .t/tmprepo73/.git/annex/keys/.nfs0000000009a305870000020e: removeDirectoryRecursive: resource busy (Device or resource busy) +sleeping 10 seconds and will retry directory cleanup +FAIL +-- + 0993b09..c09ddc4 git-annex -> synced/git-annex + a823824..520f58c master -> synced/master +OK (13.67s) + addurl: .t/tmprepo73/.git/annex/keys/.nfs0000000009a305870000020e: removeDirectoryRecursive: resource busy (Device or resource busy) +sleeping 10 seconds and will retry directory cleanup +FAIL +-- +OK (14.59s) + addurl: On branch master +nothing to commit, working directory clean +.t/tmprepo73/.git/annex/keys/.nfs0000000009a305870000020e: removeDirectoryRecursive: resource busy (Device or resource busy) +sleeping 10 seconds and will retry directory cleanup +FAIL + + +# End of transcript or log. +"""]] + +[[!meta author=yoh]] From 08c3c165decdeee1ac12f742877ddde9cc65f045 Mon Sep 17 00:00:00 2001 From: torpidus Date: Tue, 8 Mar 2016 21:36:24 +0000 Subject: [PATCH 43/58] --- ...messed_up_annex_by_using_git_checkout.mdwn | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 doc/tips/messed_up_annex_by_using_git_checkout.mdwn diff --git a/doc/tips/messed_up_annex_by_using_git_checkout.mdwn b/doc/tips/messed_up_annex_by_using_git_checkout.mdwn new file mode 100644 index 0000000000..f9b2eb63c4 --- /dev/null +++ b/doc/tips/messed_up_annex_by_using_git_checkout.mdwn @@ -0,0 +1,40 @@ +Hello. Linux experienced user here, but with no development or git experience ever. This directly leads me to my biggest trouble with git-annex because I constantly suffer from misunderstanding each and everything. That being said, my problem is the following: I had the terrible idea to have my .thunderbird directory synchronized over several machines, leading the thunderbird profile to total corruption because after a few weeks I finally managed to have multiple machines accessing it. As I started trying to recover, things got worse and this is my last seek for help before starting over by creating the repositories from scratch. + +What I did: + +1. I did some research on how to recover an old state of the repo, which should not have been a problem because there is a "full backup" repo. I came across this [1] page and the pain started with me looking for my wanted commit to roll-back in "git log" and then did some tries in the way something like, "git checkout -b old-state4 012345678". + +2. Of course this recovered the whole repo and not only thunderbird, so I used a file synchronizer to put everything else back into place after the action. + +3. Unfortunately, the "branches" seem to have been messed up and the repos are no longer in sync. + +This is what the machine says that I have used to create the mess: + + [2016-03-08 19:15:26.915116] Pusher: Syncing with host123 + (recording state in git...) + To ssh://user@10.0.0.1/mnt/foo/bar + d35c699..fed0636 git-annex -> synced/git-annex + a44bfb2..818b7b5 annex/direct/old_state4 -> synced/old_state4 + +This is what another machine says: + + [2016-03-08 21:17:48.649949] Pusher: Syncing with host123 + (recording state in git...) + To ssh://user@10.0.0.1/mnt/foo/bar + + 423f50f..4c8fad8 annex/direct/master -> q/annex/direct/master + 2a67458..fed0636 git-annex -> host123/git-annex + 6a1076b..4c8fad8 master -> host123/master + 7f55414..818b7b5 old_state4 -> host123/old_state4 + +Long story, short... + +I apologize for being a total git noob while at the same time performing git magic leading into a total desaster. +However, I hope someone can give me a hint what to do to have the "old_state4" solved? + +Also, I really would like to get used to the git internals but since git is quite powerful, I always get overwhelmed because the tutorials out there are either developer-focused (which I'm not in the correct target group) or they simply cover each and everything (which is of no use because I don't want to administrate a GitHub repo but a private git-annex for my files and documents). + +Thank you so much! + + +[1] http://stackoverflow.com/questions/4114095/revert-git-repo-to-a-previous-commit From 7007c23cc5b5f3ecb869437bba23bdc680bfb140 Mon Sep 17 00:00:00 2001 From: nasava Date: Tue, 8 Mar 2016 22:02:29 +0000 Subject: [PATCH 44/58] Added a comment: Ancient variant for Armel --- .../comment_3_eaa9b0532d4629b61f3a684886b1d4f9._comment | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 doc/install/Linux_standalone/comment_3_eaa9b0532d4629b61f3a684886b1d4f9._comment diff --git a/doc/install/Linux_standalone/comment_3_eaa9b0532d4629b61f3a684886b1d4f9._comment b/doc/install/Linux_standalone/comment_3_eaa9b0532d4629b61f3a684886b1d4f9._comment new file mode 100644 index 0000000000..62ab93ca88 --- /dev/null +++ b/doc/install/Linux_standalone/comment_3_eaa9b0532d4629b61f3a684886b1d4f9._comment @@ -0,0 +1,7 @@ +[[!comment format=mdwn + username="nasava" + subject="Ancient variant for Armel" + date="2016-03-08T22:02:29Z" + content=""" +I have a NAS running Linux Kernel 2.6.36 unfortunately not possible updating it. The newest standalone build complains about \"kernel too old\". Is there a variant somewhere for ancient armel also like for x86_32? Or how can I build one? +"""]] From ec376cf1cb87372e2e429a2cd64c2ca19e2666fb Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 9 Mar 2016 00:34:18 -0400 Subject: [PATCH 45/58] adjust architecture lists --- debian/control | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/debian/control b/debian/control index d2f6e5c64f..21c7a8bcef 100644 --- a/debian/control +++ b/debian/control @@ -31,18 +31,18 @@ Build-Depends: libghc-stm-dev (>= 2.3), libghc-dbus-dev (>= 0.10.7) [linux-any], libghc-fdo-notify-dev (>= 0.3) [linux-any], - libghc-yesod-dev (>= 1.2.6.1) [i386 amd64 arm64 armhf kfreebsd-i386 kfreebsd-amd64 mips mipsel powerpc ppc64el s390x], - libghc-yesod-core-dev (>= 1.2.19) [i386 amd64 arm64 armhf kfreebsd-i386 kfreebsd-amd64 mips mipsel powerpc ppc64el s390x], - libghc-yesod-form-dev (>= 1.3.15) [i386 amd64 arm64 armhf kfreebsd-i386 kfreebsd-amd64 mips mipsel powerpc ppc64el s390x], - libghc-yesod-static-dev (>= 1.2.4) [i386 amd64 arm64 armhf kfreebsd-i386 kfreebsd-amd64 mips mipsel powerpc ppc64el s390x], - libghc-yesod-default-dev (>= 1.2.0) [i386 amd64 arm64 armhf kfreebsd-i386 kfreebsd-amd64 mips mipsel powerpc ppc64el s390x], - libghc-shakespeare-dev (>= 2.0.0) [i386 amd64 arm64 armhf kfreebsd-i386 kfreebsd-amd64 mips mipsel powerpc ppc64el s390x], - libghc-clientsession-dev [i386 amd64 arm64 armhf kfreebsd-i386 kfreebsd-amd64 mips mipsel powerpc ppc64el s390x], - libghc-warp-dev (>= 3.0.0.5) [i386 amd64 arm64 armhf kfreebsd-i386 kfreebsd-amd64 mips mipsel powerpc ppc64el s390x], - libghc-warp-tls-dev [i386 amd64 arm64 armhf kfreebsd-i386 kfreebsd-amd64 mips mipsel powerpc ppc64el s390x], - libghc-wai-dev [i386 amd64 arm64 armhf kfreebsd-i386 kfreebsd-amd64 mips mipsel powerpc ppc64el s390x], - libghc-wai-extra-dev [i386 amd64 arm64 armhf kfreebsd-i386 kfreebsd-amd64 mips mipsel powerpc ppc64el s390x], - libghc-dav-dev (>= 1.0) [i386 amd64 arm64 armhf kfreebsd-i386 kfreebsd-amd64 mips mips64el mipsel powerpc ppc64el s390x sparc64 hppa alpha hurd-i386], + libghc-yesod-dev (>= 1.2.6.1) [i386 amd64 arm64 armhf kfreebsd-amd64 kfreebsd-i386 mips mips64el mipsel powerpc ppc64el s390x] + libghc-yesod-core-dev (>= 1.2.19) [i386 amd64 arm64 armhf kfreebsd-i386 kfreebsd-amd64 mips mips64el mipsel powerpc ppc64el s390x], + libghc-yesod-form-dev (>= 1.3.15) [i386 amd64 arm64 armhf kfreebsd-i386 kfreebsd-amd64 mips mips64el mipsel powerpc ppc64el s390x], + libghc-yesod-static-dev (>= 1.2.4) [i386 amd64 arm64 armhf kfreebsd-i386 kfreebsd-amd64 mips mips64el mipsel powerpc ppc64el s390x], + libghc-yesod-default-dev (>= 1.2.0) [i386 amd64 arm64 armhf kfreebsd-i386 kfreebsd-amd64 mips mips64el mipsel powerpc ppc64el s390x], + libghc-shakespeare-dev (>= 2.0.0) [i386 amd64 arm64 armhf kfreebsd-i386 kfreebsd-amd64 mips mips64el mipsel powerpc ppc64el s390x], + libghc-clientsession-dev [i386 amd64 arm64 armhf kfreebsd-i386 kfreebsd-amd64 mips mips64el mipsel powerpc ppc64el s390x], + libghc-warp-dev (>= 3.0.0.5) [i386 amd64 arm64 armhf kfreebsd-i386 kfreebsd-amd64 mips mips64el mipsel powerpc ppc64el s390x], + libghc-warp-tls-dev [i386 amd64 arm64 armhf kfreebsd-i386 kfreebsd-amd64 mips mips64el mipsel powerpc ppc64el s390x], + libghc-wai-dev [i386 amd64 arm64 armhf kfreebsd-i386 kfreebsd-amd64 mips mips64el mipsel powerpc ppc64el s390x], + libghc-wai-extra-dev [i386 amd64 arm64 armhf kfreebsd-i386 kfreebsd-amd64 mips mips64el mipsel powerpc ppc64el s390x], + libghc-dav-dev (>= 1.0) libghc-persistent-dev, libghc-persistent-template-dev, libghc-persistent-sqlite-dev, From 9f091ea5e8c4f2b0c489031cc2dae271bed54be9 Mon Sep 17 00:00:00 2001 From: ellis Date: Wed, 9 Mar 2016 10:04:15 +0000 Subject: [PATCH 46/58] Added a comment --- ..._d8c8077e4dc1e0660d082482012b6594._comment | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 doc/bugs/git-annex:_failed_to_lock_content/comment_5_d8c8077e4dc1e0660d082482012b6594._comment diff --git a/doc/bugs/git-annex:_failed_to_lock_content/comment_5_d8c8077e4dc1e0660d082482012b6594._comment b/doc/bugs/git-annex:_failed_to_lock_content/comment_5_d8c8077e4dc1e0660d082482012b6594._comment new file mode 100644 index 0000000000..2f3e560faa --- /dev/null +++ b/doc/bugs/git-annex:_failed_to_lock_content/comment_5_d8c8077e4dc1e0660d082482012b6594._comment @@ -0,0 +1,28 @@ +[[!comment format=mdwn + username="ellis" + subject="comment 5" + date="2016-03-09T10:04:14Z" + content=""" +1) I'm afraid I don't have any real knowledge of VFAT -- always avoided it, but this is a shared drive, so it seemed best to just leave it with the factory formatting. + +2) The output from `mount` is shown at the bottom of comment 3. The drive gets automounted when I plug it in. + +3) \"Can you chmod the file to have some mode other than 444?\" + +Yes. Here's a console transcript. After running `chmod 644`, git annex was able to drop the file. + + + % cd /media/ellis/USB04/repo/taiji-lib + + % ls -l ./annex/objects/97e/78c/SHA256E-s38464078--0db38599ed526d248857015c7b8e1b177af646939f8e0c8004b17a931ce2e101.wav/SHA256E-s38464078--0db38599ed526d248857015c7b8e1b177af646939f8e0c8004b17a931ce2e101.wav + -r--r--r-- 1 ellis ellis 38464078 Mär 4 18:32 ./annex/objects/97e/78c/SHA256E-s38464078--0db38599ed526d248857015c7b8e1b177af646939f8e0c8004b17a931ce2e101.wav/SHA256E-s38464078--0db38599ed526d248857015c7b8e1b177af646939f8e0c8004b17a931ce2e101.wav + + % chmod 644 ./annex/objects/97e/78c/SHA256E-s38464078--0db38599ed526d248857015c7b8e1b177af646939f8e0c8004b17a931ce2e101.wav/SHA256E-s38464078--0db38599ed526d248857015c7b8e1b177af646939f8e0c8004b17a931ce2e101.wav + + % ls -l ./annex/objects/97e/78c/SHA256E-s38464078--0db38599ed526d248857015c7b8e1b177af646939f8e0c8004b17a931ce2e101.wav/SHA256E-s38464078--0db38599ed526d248857015c7b8e1b177af646939f8e0c8004b17a931ce2e101.wav + -rw-r--r-- 1 ellis ellis 38464078 Mär 4 18:32 ./annex/objects/97e/78c/SHA256E-s38464078--0db38599ed526d248857015c7b8e1b177af646939f8e0c8004b17a931ce2e101.wav/SHA256E-s38464078--0db38599ed526d248857015c7b8e1b177af646939f8e0c8004b17a931ce2e101.wav + + % git annex dropunused 101 --force + dropunused 101 ok + (recording state in git...) +"""]] From 83d321a72cbf0f361d0d97b926d98e50d16ab182 Mon Sep 17 00:00:00 2001 From: "mail@f1d77c48f528d8c7b885900281887e045ad5114e" Date: Wed, 9 Mar 2016 11:24:27 +0000 Subject: [PATCH 47/58] --- doc/bugs/hash_changed.mdwn | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 doc/bugs/hash_changed.mdwn diff --git a/doc/bugs/hash_changed.mdwn b/doc/bugs/hash_changed.mdwn new file mode 100644 index 0000000000..cb1c1eefe3 --- /dev/null +++ b/doc/bugs/hash_changed.mdwn @@ -0,0 +1,27 @@ +### Please describe the problem. + +I ran `git annex fsck` on some files, and the fsck reported that hashes were incorrect and the files were moved. + +### What steps will reproduce the problem? + +I don't know. + +### What version of git-annex are you using? On what operating system? + +``` +git-annex version: 6.20160229 +build flags: Assistant Webapp Pairing Testsuite S3(multipartupload)(storageclasses) WebDAV Inotify DBus DesktopNotify XMPP ConcurrentOutput TorrentParser MagicMime Feeds Quvi +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 SHA1E SHA1 MD5E MD5 WORM URL +remote types: git gcrypt S3 bup directory rsync web bittorrent webdav tahoe glacier ddar hook external +``` + +on NixOS linux 64 bit - unstable channel + +### Please provide any additional information below. + +The problem was on several disks, different manufacturer, different disk size, etc. The fsck always transformed hashA -> hashB, so the hashes were equal before and after the fsck run on all disks, though the link to the "old" file was not fixed to point to the "new" file. + +### 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 use annex for years now, never had a problem with it. It is one of the most awesome pieces of software I've seen in the last 10 years, though I only use a really small part of it. Sometimes it bugs me a little that it consumes quite a lot of memory on large repositories, though most of the time this is not an issue for me. + From 8f8ccc389955a03a7e09efd998b3e060817ce561 Mon Sep 17 00:00:00 2001 From: "mail@f1d77c48f528d8c7b885900281887e045ad5114e" Date: Wed, 9 Mar 2016 16:03:35 +0000 Subject: [PATCH 48/58] Added a comment: Solution --- ...comment_1_7ec190a665b50eefadff59949a576bbb._comment | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 doc/bugs/hash_changed/comment_1_7ec190a665b50eefadff59949a576bbb._comment diff --git a/doc/bugs/hash_changed/comment_1_7ec190a665b50eefadff59949a576bbb._comment b/doc/bugs/hash_changed/comment_1_7ec190a665b50eefadff59949a576bbb._comment new file mode 100644 index 0000000000..87cbdedfc9 --- /dev/null +++ b/doc/bugs/hash_changed/comment_1_7ec190a665b50eefadff59949a576bbb._comment @@ -0,0 +1,10 @@ +[[!comment format=mdwn + username="mail@f1d77c48f528d8c7b885900281887e045ad5114e" + nickname="mail" + subject="Solution" + date="2016-03-09T16:03:35Z" + content=""" +The solution proposed by \"joeyh\" on irc was to remove the symlink (`git rm` it) and then move the actual file from .git/annex/bad back to the file and `git annex add` it again. + +Worked beautifully. +"""]] From 3b081713ed8b042614315b77c2e9ebaacc4b1190 Mon Sep 17 00:00:00 2001 From: "viric@582d0845fdeae54b262502f49509b4577a5adbf8" Date: Wed, 9 Mar 2016 16:44:05 +0000 Subject: [PATCH 49/58] --- doc/todo/add_sftp_backend.mdwn | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 doc/todo/add_sftp_backend.mdwn diff --git a/doc/todo/add_sftp_backend.mdwn b/doc/todo/add_sftp_backend.mdwn new file mode 100644 index 0000000000..386fec3c8a --- /dev/null +++ b/doc/todo/add_sftp_backend.mdwn @@ -0,0 +1,3 @@ +A sftp backend would be nice because gpg operations could be pipelined to the network transfer, not requiring the creation of a full file to disk with gpg before the network transmission, as it happens with rsync. + +There should be some libraries that can handle the sftp connections and transfers. I read that even curl has support for that. From c6f81e8ef5fdd341c9120429f8de7862bef69140 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 9 Mar 2016 12:54:22 -0400 Subject: [PATCH 50/58] done --- doc/todo/add_magicmime_support_to_OSX_dmg.mdwn | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/todo/add_magicmime_support_to_OSX_dmg.mdwn b/doc/todo/add_magicmime_support_to_OSX_dmg.mdwn index 9e4e8f3870..ef69869ba6 100644 --- a/doc/todo/add_magicmime_support_to_OSX_dmg.mdwn +++ b/doc/todo/add_magicmime_support_to_OSX_dmg.mdwn @@ -1,3 +1,5 @@ The OSX .dmg is built without the MagicMime build flag. Turning it on will take some work to ship a copy of the magic database inside the dmg. + +> [[done]] --[[Joey]] From 0cdd4f9f5874e9cbe27f9b678595c7948db763b6 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 9 Mar 2016 13:13:28 -0400 Subject: [PATCH 51/58] Merge branch 'master' of ssh://git-annex.branchable.com --- ..._d8c8077e4dc1e0660d082482012b6594._comment | 28 ++++++++++ doc/bugs/hash_changed.mdwn | 27 ++++++++++ ..._7ec190a665b50eefadff59949a576bbb._comment | 10 ++++ ...me_tests_fail_while_running_under_NFS.mdwn | 54 +++++++++++++++++++ ..._eaa9b0532d4629b61f3a684886b1d4f9._comment | 7 +++ ...messed_up_annex_by_using_git_checkout.mdwn | 40 ++++++++++++++ doc/todo/add_sftp_backend.mdwn | 3 ++ 7 files changed, 169 insertions(+) create mode 100644 doc/bugs/git-annex:_failed_to_lock_content/comment_5_d8c8077e4dc1e0660d082482012b6594._comment create mode 100644 doc/bugs/hash_changed.mdwn create mode 100644 doc/bugs/hash_changed/comment_1_7ec190a665b50eefadff59949a576bbb._comment create mode 100644 doc/bugs/some_tests_fail_while_running_under_NFS.mdwn create mode 100644 doc/install/Linux_standalone/comment_3_eaa9b0532d4629b61f3a684886b1d4f9._comment create mode 100644 doc/tips/messed_up_annex_by_using_git_checkout.mdwn create mode 100644 doc/todo/add_sftp_backend.mdwn diff --git a/doc/bugs/git-annex:_failed_to_lock_content/comment_5_d8c8077e4dc1e0660d082482012b6594._comment b/doc/bugs/git-annex:_failed_to_lock_content/comment_5_d8c8077e4dc1e0660d082482012b6594._comment new file mode 100644 index 0000000000..2f3e560faa --- /dev/null +++ b/doc/bugs/git-annex:_failed_to_lock_content/comment_5_d8c8077e4dc1e0660d082482012b6594._comment @@ -0,0 +1,28 @@ +[[!comment format=mdwn + username="ellis" + subject="comment 5" + date="2016-03-09T10:04:14Z" + content=""" +1) I'm afraid I don't have any real knowledge of VFAT -- always avoided it, but this is a shared drive, so it seemed best to just leave it with the factory formatting. + +2) The output from `mount` is shown at the bottom of comment 3. The drive gets automounted when I plug it in. + +3) \"Can you chmod the file to have some mode other than 444?\" + +Yes. Here's a console transcript. After running `chmod 644`, git annex was able to drop the file. + + + % cd /media/ellis/USB04/repo/taiji-lib + + % ls -l ./annex/objects/97e/78c/SHA256E-s38464078--0db38599ed526d248857015c7b8e1b177af646939f8e0c8004b17a931ce2e101.wav/SHA256E-s38464078--0db38599ed526d248857015c7b8e1b177af646939f8e0c8004b17a931ce2e101.wav + -r--r--r-- 1 ellis ellis 38464078 Mär 4 18:32 ./annex/objects/97e/78c/SHA256E-s38464078--0db38599ed526d248857015c7b8e1b177af646939f8e0c8004b17a931ce2e101.wav/SHA256E-s38464078--0db38599ed526d248857015c7b8e1b177af646939f8e0c8004b17a931ce2e101.wav + + % chmod 644 ./annex/objects/97e/78c/SHA256E-s38464078--0db38599ed526d248857015c7b8e1b177af646939f8e0c8004b17a931ce2e101.wav/SHA256E-s38464078--0db38599ed526d248857015c7b8e1b177af646939f8e0c8004b17a931ce2e101.wav + + % ls -l ./annex/objects/97e/78c/SHA256E-s38464078--0db38599ed526d248857015c7b8e1b177af646939f8e0c8004b17a931ce2e101.wav/SHA256E-s38464078--0db38599ed526d248857015c7b8e1b177af646939f8e0c8004b17a931ce2e101.wav + -rw-r--r-- 1 ellis ellis 38464078 Mär 4 18:32 ./annex/objects/97e/78c/SHA256E-s38464078--0db38599ed526d248857015c7b8e1b177af646939f8e0c8004b17a931ce2e101.wav/SHA256E-s38464078--0db38599ed526d248857015c7b8e1b177af646939f8e0c8004b17a931ce2e101.wav + + % git annex dropunused 101 --force + dropunused 101 ok + (recording state in git...) +"""]] diff --git a/doc/bugs/hash_changed.mdwn b/doc/bugs/hash_changed.mdwn new file mode 100644 index 0000000000..cb1c1eefe3 --- /dev/null +++ b/doc/bugs/hash_changed.mdwn @@ -0,0 +1,27 @@ +### Please describe the problem. + +I ran `git annex fsck` on some files, and the fsck reported that hashes were incorrect and the files were moved. + +### What steps will reproduce the problem? + +I don't know. + +### What version of git-annex are you using? On what operating system? + +``` +git-annex version: 6.20160229 +build flags: Assistant Webapp Pairing Testsuite S3(multipartupload)(storageclasses) WebDAV Inotify DBus DesktopNotify XMPP ConcurrentOutput TorrentParser MagicMime Feeds Quvi +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 SHA1E SHA1 MD5E MD5 WORM URL +remote types: git gcrypt S3 bup directory rsync web bittorrent webdav tahoe glacier ddar hook external +``` + +on NixOS linux 64 bit - unstable channel + +### Please provide any additional information below. + +The problem was on several disks, different manufacturer, different disk size, etc. The fsck always transformed hashA -> hashB, so the hashes were equal before and after the fsck run on all disks, though the link to the "old" file was not fixed to point to the "new" file. + +### 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 use annex for years now, never had a problem with it. It is one of the most awesome pieces of software I've seen in the last 10 years, though I only use a really small part of it. Sometimes it bugs me a little that it consumes quite a lot of memory on large repositories, though most of the time this is not an issue for me. + diff --git a/doc/bugs/hash_changed/comment_1_7ec190a665b50eefadff59949a576bbb._comment b/doc/bugs/hash_changed/comment_1_7ec190a665b50eefadff59949a576bbb._comment new file mode 100644 index 0000000000..87cbdedfc9 --- /dev/null +++ b/doc/bugs/hash_changed/comment_1_7ec190a665b50eefadff59949a576bbb._comment @@ -0,0 +1,10 @@ +[[!comment format=mdwn + username="mail@f1d77c48f528d8c7b885900281887e045ad5114e" + nickname="mail" + subject="Solution" + date="2016-03-09T16:03:35Z" + content=""" +The solution proposed by \"joeyh\" on irc was to remove the symlink (`git rm` it) and then move the actual file from .git/annex/bad back to the file and `git annex add` it again. + +Worked beautifully. +"""]] diff --git a/doc/bugs/some_tests_fail_while_running_under_NFS.mdwn b/doc/bugs/some_tests_fail_while_running_under_NFS.mdwn new file mode 100644 index 0000000000..2e87ff8a5b --- /dev/null +++ b/doc/bugs/some_tests_fail_while_running_under_NFS.mdwn @@ -0,0 +1,54 @@ +### Please describe the problem. + +4 out of 269 tests failed (4468.00s) + +hard to assess how critical they are... + +### What steps will reproduce the problem? + +run git annex test + +### What version of git-annex are you using? On what operating system? + +6.20160307+gitgb095561-1~ndall+1 + +### Please provide any additional information below. + +[Full log](http://www.onerussian.com/tmp/git-annex-tests-6.20160307+gitgb095561-1~ndall+1.log) + +[[!format sh """ +smaug:/mnt/nfs/scrap/datalad/test_annex +$> grep -B5 FAIL git-annex-tests-6.20160307+gitgb095561-1~ndall+1.log + crypto: OK (50.57s) + preferred content: OK (20.36s) + add subdirs: OK (8.97s) + addurl: .t/tmprepo73/.git/annex/keys: removeDirectoryRecursive: unsatisfied constraints (Directory not empty) +sleeping 10 seconds and will retry directory cleanup +FAIL +-- + 293ed4c..c16b350 git-annex -> synced/git-annex + dd272eb..ffe1721 master -> synced/master +OK (11.64s) + addurl: .t/tmprepo73/.git/annex/keys/.nfs0000000009a305870000020e: removeDirectoryRecursive: resource busy (Device or resource busy) +sleeping 10 seconds and will retry directory cleanup +FAIL +-- + 0993b09..c09ddc4 git-annex -> synced/git-annex + a823824..520f58c master -> synced/master +OK (13.67s) + addurl: .t/tmprepo73/.git/annex/keys/.nfs0000000009a305870000020e: removeDirectoryRecursive: resource busy (Device or resource busy) +sleeping 10 seconds and will retry directory cleanup +FAIL +-- +OK (14.59s) + addurl: On branch master +nothing to commit, working directory clean +.t/tmprepo73/.git/annex/keys/.nfs0000000009a305870000020e: removeDirectoryRecursive: resource busy (Device or resource busy) +sleeping 10 seconds and will retry directory cleanup +FAIL + + +# End of transcript or log. +"""]] + +[[!meta author=yoh]] diff --git a/doc/install/Linux_standalone/comment_3_eaa9b0532d4629b61f3a684886b1d4f9._comment b/doc/install/Linux_standalone/comment_3_eaa9b0532d4629b61f3a684886b1d4f9._comment new file mode 100644 index 0000000000..62ab93ca88 --- /dev/null +++ b/doc/install/Linux_standalone/comment_3_eaa9b0532d4629b61f3a684886b1d4f9._comment @@ -0,0 +1,7 @@ +[[!comment format=mdwn + username="nasava" + subject="Ancient variant for Armel" + date="2016-03-08T22:02:29Z" + content=""" +I have a NAS running Linux Kernel 2.6.36 unfortunately not possible updating it. The newest standalone build complains about \"kernel too old\". Is there a variant somewhere for ancient armel also like for x86_32? Or how can I build one? +"""]] diff --git a/doc/tips/messed_up_annex_by_using_git_checkout.mdwn b/doc/tips/messed_up_annex_by_using_git_checkout.mdwn new file mode 100644 index 0000000000..f9b2eb63c4 --- /dev/null +++ b/doc/tips/messed_up_annex_by_using_git_checkout.mdwn @@ -0,0 +1,40 @@ +Hello. Linux experienced user here, but with no development or git experience ever. This directly leads me to my biggest trouble with git-annex because I constantly suffer from misunderstanding each and everything. That being said, my problem is the following: I had the terrible idea to have my .thunderbird directory synchronized over several machines, leading the thunderbird profile to total corruption because after a few weeks I finally managed to have multiple machines accessing it. As I started trying to recover, things got worse and this is my last seek for help before starting over by creating the repositories from scratch. + +What I did: + +1. I did some research on how to recover an old state of the repo, which should not have been a problem because there is a "full backup" repo. I came across this [1] page and the pain started with me looking for my wanted commit to roll-back in "git log" and then did some tries in the way something like, "git checkout -b old-state4 012345678". + +2. Of course this recovered the whole repo and not only thunderbird, so I used a file synchronizer to put everything else back into place after the action. + +3. Unfortunately, the "branches" seem to have been messed up and the repos are no longer in sync. + +This is what the machine says that I have used to create the mess: + + [2016-03-08 19:15:26.915116] Pusher: Syncing with host123 + (recording state in git...) + To ssh://user@10.0.0.1/mnt/foo/bar + d35c699..fed0636 git-annex -> synced/git-annex + a44bfb2..818b7b5 annex/direct/old_state4 -> synced/old_state4 + +This is what another machine says: + + [2016-03-08 21:17:48.649949] Pusher: Syncing with host123 + (recording state in git...) + To ssh://user@10.0.0.1/mnt/foo/bar + + 423f50f..4c8fad8 annex/direct/master -> q/annex/direct/master + 2a67458..fed0636 git-annex -> host123/git-annex + 6a1076b..4c8fad8 master -> host123/master + 7f55414..818b7b5 old_state4 -> host123/old_state4 + +Long story, short... + +I apologize for being a total git noob while at the same time performing git magic leading into a total desaster. +However, I hope someone can give me a hint what to do to have the "old_state4" solved? + +Also, I really would like to get used to the git internals but since git is quite powerful, I always get overwhelmed because the tutorials out there are either developer-focused (which I'm not in the correct target group) or they simply cover each and everything (which is of no use because I don't want to administrate a GitHub repo but a private git-annex for my files and documents). + +Thank you so much! + + +[1] http://stackoverflow.com/questions/4114095/revert-git-repo-to-a-previous-commit diff --git a/doc/todo/add_sftp_backend.mdwn b/doc/todo/add_sftp_backend.mdwn new file mode 100644 index 0000000000..386fec3c8a --- /dev/null +++ b/doc/todo/add_sftp_backend.mdwn @@ -0,0 +1,3 @@ +A sftp backend would be nice because gpg operations could be pipelined to the network transfer, not requiring the creation of a full file to disk with gpg before the network transmission, as it happens with rsync. + +There should be some libraries that can handle the sftp connections and transfers. I read that even curl has support for that. From 5e0843e4b8e4ad3b3855c6aeaf724fae96e78354 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 9 Mar 2016 13:14:27 -0400 Subject: [PATCH 52/58] close --- doc/bugs/hash_changed.mdwn | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/bugs/hash_changed.mdwn b/doc/bugs/hash_changed.mdwn index cb1c1eefe3..44f2d2ebab 100644 --- a/doc/bugs/hash_changed.mdwn +++ b/doc/bugs/hash_changed.mdwn @@ -25,3 +25,8 @@ The problem was on several disks, different manufacturer, different disk size, e I use annex for years now, never had a problem with it. It is one of the most awesome pieces of software I've seen in the last 10 years, though I only use a really small part of it. Sometimes it bugs me a little that it consumes quite a lot of memory on large repositories, though most of the time this is not an issue for me. +> I think this was not a bug in hashing, just a corrupted file that +> spread to several repositories. More recent git-annex versions checksum +> files after transfer so detect the problem. +> +> Since it was resolved to reporter's satisfaction, [[done]] --[[Joey]] From e4c22ad5bb000d69609840deb08b5253e181beff Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 9 Mar 2016 13:15:43 -0400 Subject: [PATCH 53/58] comment --- .../comment_1_8e0f72f633ec79bd373b009046ab66b7._comment | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 doc/bugs/some_tests_fail_while_running_under_NFS/comment_1_8e0f72f633ec79bd373b009046ab66b7._comment diff --git a/doc/bugs/some_tests_fail_while_running_under_NFS/comment_1_8e0f72f633ec79bd373b009046ab66b7._comment b/doc/bugs/some_tests_fail_while_running_under_NFS/comment_1_8e0f72f633ec79bd373b009046ab66b7._comment new file mode 100644 index 0000000000..f52704041d --- /dev/null +++ b/doc/bugs/some_tests_fail_while_running_under_NFS/comment_1_8e0f72f633ec79bd373b009046ab66b7._comment @@ -0,0 +1,8 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 1""" + date="2016-03-09T17:15:13Z" + content=""" +This is all down to those nfs lock files, so finding a way to probe for an +NFS system and auto-enable pidlock is the best way to fix this. +"""]] From d201e6c359367b28023acde58dff07dedd89e226 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 9 Mar 2016 13:21:55 -0400 Subject: [PATCH 54/58] add todo from comment --- ...comment_4_070689ea45739d06260da07d1369dff9._comment | 7 +++++++ doc/todo/add_ancient_armel_build.mdwn | 10 ++++++++++ 2 files changed, 17 insertions(+) create mode 100644 doc/install/Linux_standalone/comment_4_070689ea45739d06260da07d1369dff9._comment create mode 100644 doc/todo/add_ancient_armel_build.mdwn diff --git a/doc/install/Linux_standalone/comment_4_070689ea45739d06260da07d1369dff9._comment b/doc/install/Linux_standalone/comment_4_070689ea45739d06260da07d1369dff9._comment new file mode 100644 index 0000000000..61ed0ff34d --- /dev/null +++ b/doc/install/Linux_standalone/comment_4_070689ea45739d06260da07d1369dff9._comment @@ -0,0 +1,7 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 4""" + date="2016-03-09T17:16:54Z" + content=""" +I've opened a todo, [[todo/add_ancient_armel_build]] +"""]] diff --git a/doc/todo/add_ancient_armel_build.mdwn b/doc/todo/add_ancient_armel_build.mdwn new file mode 100644 index 0000000000..52ce1a73da --- /dev/null +++ b/doc/todo/add_ancient_armel_build.mdwn @@ -0,0 +1,10 @@ +Add an armel build like the i386ancient build. + +The current arm autobuilder doesn't have enough free space for the chroot +this would need. I need to upgrade its microsd card first, adding +approximately 5 gb. (A 16 gb card would suffice.) + +Now, it would be possible to switch it to only do an ancient build, +instead of the current modern build. The downside of that is the ancient +build environment uses debian stable, so it has old versions of git, +libraries etc, that go into the build. --[[Joey]] From 9039bdb4ea79b308947caabea5f1d5c1f218abf2 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 9 Mar 2016 13:33:13 -0400 Subject: [PATCH 55/58] Always try to thaw content, even when annex.crippledfilesystem is set. --- Annex/Content.hs | 9 +++++++-- Annex/Perms.hs | 11 +++++++++-- debian/changelog | 1 + doc/bugs/git-annex:_failed_to_lock_content.mdwn | 2 ++ ...omment_6_ced3c56607762562c1d21fd821d7c779._comment | 11 +++++++++++ 5 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 doc/bugs/git-annex:_failed_to_lock_content/comment_6_ced3c56607762562c1d21fd821d7c779._comment diff --git a/Annex/Content.hs b/Annex/Content.hs index 103fa264d4..d14e87adcd 100644 --- a/Annex/Content.hs +++ b/Annex/Content.hs @@ -951,8 +951,13 @@ chmodContent file = unlessM crippledFileSystem $ {- Allows writing to an annexed file that freezeContent was called on - before. -} thawContent :: FilePath -> Annex () -thawContent file = unlessM crippledFileSystem $ - withShared go +thawContent file = ifM crippledFileSystem + -- Probably cannot change mode on crippled filesystem, + -- but if file modes are supported, the content may be frozen + -- so try to thaw it. + ( void $ tryNonAsync $ withShared go + , withShared go + ) where go GroupShared = liftIO $ groupWriteRead file go AllShared = liftIO $ groupWriteRead file diff --git a/Annex/Perms.hs b/Annex/Perms.hs index 159cc328a1..3905b7af9c 100644 --- a/Annex/Perms.hs +++ b/Annex/Perms.hs @@ -92,8 +92,15 @@ freezeContentDir file = unlessM crippledFileSystem $ go _ = liftIO $ preventWrite dir thawContentDir :: FilePath -> Annex () -thawContentDir file = unlessM crippledFileSystem $ - liftIO $ allowWrite $ parentDir file +thawContentDir file = ifM crippledFileSystem + -- Probably cannot change mode on crippled filesystem, + -- but if file modes are supported, the directory may be frozen, + -- so try to thaw it. + ( void $ tryNonAsync go + , go + ) + where + go = liftIO $ allowWrite $ parentDir file {- Makes the directory tree to store an annexed file's content, - with appropriate permissions on each level. -} diff --git a/debian/changelog b/debian/changelog index fe8d0cb1ad..fc01dbdafa 100644 --- a/debian/changelog +++ b/debian/changelog @@ -11,6 +11,7 @@ git-annex (6.20160230) UNRELEASED; urgency=medium * dropkey: Add --batch and --json. * Fix OSX dmg to include libraries needed by bundled gpg, lost in last release. + * Always try to thaw content, even when annex.crippledfilesystem is set. -- Joey Hess Mon, 29 Feb 2016 13:00:30 -0400 diff --git a/doc/bugs/git-annex:_failed_to_lock_content.mdwn b/doc/bugs/git-annex:_failed_to_lock_content.mdwn index f383f30ffd..f036f1353e 100644 --- a/doc/bugs/git-annex:_failed_to_lock_content.mdwn +++ b/doc/bugs/git-annex:_failed_to_lock_content.mdwn @@ -103,3 +103,5 @@ Could the problem have something to do with the file having permission 0444 and ### 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) Been using it since your kickstarter campaign! + +> [[done]] --[[Joey]] diff --git a/doc/bugs/git-annex:_failed_to_lock_content/comment_6_ced3c56607762562c1d21fd821d7c779._comment b/doc/bugs/git-annex:_failed_to_lock_content/comment_6_ced3c56607762562c1d21fd821d7c779._comment new file mode 100644 index 0000000000..cebc1f0c13 --- /dev/null +++ b/doc/bugs/git-annex:_failed_to_lock_content/comment_6_ced3c56607762562c1d21fd821d7c779._comment @@ -0,0 +1,11 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 6""" + date="2016-03-09T17:31:18Z" + content=""" +Ok, I managed to get a vfat that honors file perms with those mount +options. + +I'm going to make git-annex always try to chmod the file, even if it's on a +crippled filesystem. That should solve it. +"""]] From 276a67184ca4da321ca2867cdcbf7b2e07803bec Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 9 Mar 2016 13:39:00 -0400 Subject: [PATCH 56/58] fix typo in flags --- standalone/android/install-haskell-packages | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/standalone/android/install-haskell-packages b/standalone/android/install-haskell-packages index ea5f160d29..0e6b8cba45 100755 --- a/standalone/android/install-haskell-packages +++ b/standalone/android/install-haskell-packages @@ -65,7 +65,7 @@ patched () { installgitannexdeps () { pushd ../.. ln -sf standalone/android/cabal.config - cabal install --only-dependencies --flags="-magicmime -concurrent-output" "$@" # --force-reinstalls --reinstall + cabal install --only-dependencies --flags="-magicmime -concurrentoutput" "$@" # --force-reinstalls --reinstall rm -f cabal.config popd } From 4b3355cf3c2025c03c67ddef4e927847001c1b77 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 9 Mar 2016 13:43:22 -0400 Subject: [PATCH 57/58] refactor --- Annex/Content.hs | 49 ------------------------------------ Annex/Perms.hs | 62 +++++++++++++++++++++++++++++++++++++++------- Command/Unannex.hs | 1 + Command/Unlock.hs | 1 + 4 files changed, 55 insertions(+), 58 deletions(-) diff --git a/Annex/Content.hs b/Annex/Content.hs index d14e87adcd..9c4c1d5b8d 100644 --- a/Annex/Content.hs +++ b/Annex/Content.hs @@ -41,8 +41,6 @@ module Annex.Content ( saveState, downloadUrl, preseedTmp, - freezeContent, - thawContent, dirKeys, withObjectLoc, staleKeysPrune, @@ -67,7 +65,6 @@ import Utility.CopyFile import Utility.Metered import Config import Git.FilePath -import Git.SharedRepository import Annex.Perms import Annex.Link import qualified Annex.Content.Direct as Direct @@ -917,52 +914,6 @@ preseedTmp key file = go =<< inAnnex key ) ) -{- Normally, blocks writing to an annexed file, and modifies file - - permissions to allow reading it. - - - - When core.sharedRepository is set, the write bits are not removed from - - the file, but instead the appropriate group write bits are set. This is - - necessary to let other users in the group lock the file. - -} -freezeContent :: FilePath -> Annex () -freezeContent file = unlessM crippledFileSystem $ - withShared go - where - go GroupShared = liftIO $ modifyFileMode file $ - addModes [ownerReadMode, groupReadMode, ownerWriteMode, groupWriteMode] - go AllShared = liftIO $ modifyFileMode file $ - addModes (readModes ++ writeModes) - go _ = liftIO $ modifyFileMode file $ - removeModes writeModes . - addModes [ownerReadMode] - -{- Adjusts read mode of annexed file per core.sharedRepository setting. -} -chmodContent :: FilePath -> Annex () -chmodContent file = unlessM crippledFileSystem $ - withShared go - where - go GroupShared = liftIO $ modifyFileMode file $ - addModes [ownerReadMode, groupReadMode] - go AllShared = liftIO $ modifyFileMode file $ - addModes readModes - go _ = liftIO $ modifyFileMode file $ - addModes [ownerReadMode] - -{- Allows writing to an annexed file that freezeContent was called on - - before. -} -thawContent :: FilePath -> Annex () -thawContent file = ifM crippledFileSystem - -- Probably cannot change mode on crippled filesystem, - -- but if file modes are supported, the content may be frozen - -- so try to thaw it. - ( void $ tryNonAsync $ withShared go - , withShared go - ) - where - go GroupShared = liftIO $ groupWriteRead file - go AllShared = liftIO $ groupWriteRead file - go _ = liftIO $ allowWrite file - {- Finds files directly inside a directory like gitAnnexBadDir - (not in subdirectories) and returns the corresponding keys. -} dirKeys :: (Git.Repo -> FilePath) -> Annex [Key] diff --git a/Annex/Perms.hs b/Annex/Perms.hs index 3905b7af9c..4d525c127e 100644 --- a/Annex/Perms.hs +++ b/Annex/Perms.hs @@ -11,6 +11,9 @@ module Annex.Perms ( annexFileMode, createAnnexDirectory, noUmask, + freezeContent, + thawContent, + chmodContent, createContentDir, freezeContentDir, thawContentDir, @@ -77,6 +80,55 @@ createAnnexDirectory dir = walk dir [] =<< top liftIO $ createDirectoryIfMissing True p setAnnexDirPerm p +{- Normally, blocks writing to an annexed file, and modifies file + - permissions to allow reading it. + - + - When core.sharedRepository is set, the write bits are not removed from + - the file, but instead the appropriate group write bits are set. This is + - necessary to let other users in the group lock the file. + -} +freezeContent :: FilePath -> Annex () +freezeContent file = unlessM crippledFileSystem $ + withShared go + where + go GroupShared = liftIO $ modifyFileMode file $ + addModes [ownerReadMode, groupReadMode, ownerWriteMode, groupWriteMode] + go AllShared = liftIO $ modifyFileMode file $ + addModes (readModes ++ writeModes) + go _ = liftIO $ modifyFileMode file $ + removeModes writeModes . + addModes [ownerReadMode] + +{- Adjusts read mode of annexed file per core.sharedRepository setting. -} +chmodContent :: FilePath -> Annex () +chmodContent file = unlessM crippledFileSystem $ + withShared go + where + go GroupShared = liftIO $ modifyFileMode file $ + addModes [ownerReadMode, groupReadMode] + go AllShared = liftIO $ modifyFileMode file $ + addModes readModes + go _ = liftIO $ modifyFileMode file $ + addModes [ownerReadMode] + +{- Allows writing to an annexed file that freezeContent was called on + - before. -} +thawContent :: FilePath -> Annex () +thawContent file = thawPerms $ withShared go + where + go GroupShared = liftIO $ groupWriteRead file + go AllShared = liftIO $ groupWriteRead file + go _ = liftIO $ allowWrite file + +{- Runs an action that thaws a file's permissions. This will probably + - fail on a crippled filesystem. But, if file modes are supported on a + - crippled filesystem, the file may be frozen, so try to thaw it. -} +thawPerms :: Annex () -> Annex () +thawPerms a = ifM crippledFileSystem + ( void $ tryNonAsync a + , a + ) + {- Blocks writing to the directory an annexed file is in, to prevent the - file accidentially being deleted. However, if core.sharedRepository - is set, this is not done, since the group must be allowed to delete the @@ -92,15 +144,7 @@ freezeContentDir file = unlessM crippledFileSystem $ go _ = liftIO $ preventWrite dir thawContentDir :: FilePath -> Annex () -thawContentDir file = ifM crippledFileSystem - -- Probably cannot change mode on crippled filesystem, - -- but if file modes are supported, the directory may be frozen, - -- so try to thaw it. - ( void $ tryNonAsync go - , go - ) - where - go = liftIO $ allowWrite $ parentDir file +thawContentDir file = thawPerms $ liftIO $ allowWrite $ parentDir file {- Makes the directory tree to store an annexed file's content, - with appropriate permissions on each level. -} diff --git a/Command/Unannex.hs b/Command/Unannex.hs index 9e6044109e..f01d2b219d 100644 --- a/Command/Unannex.hs +++ b/Command/Unannex.hs @@ -13,6 +13,7 @@ import Command import Config import qualified Annex import Annex.Content +import Annex.Perms import Annex.Content.Direct import Annex.Version import qualified Git.Command diff --git a/Command/Unlock.hs b/Command/Unlock.hs index ded44fd2f1..ac99d5cd3a 100644 --- a/Command/Unlock.hs +++ b/Command/Unlock.hs @@ -9,6 +9,7 @@ module Command.Unlock where import Command import Annex.Content +import Annex.Perms import Annex.CatFile import Annex.Version import Annex.Link From cbd38ef36767b3a02c10723cb00d2a78479aadef Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 9 Mar 2016 15:04:00 -0400 Subject: [PATCH 58/58] remove redundant start message --- Command/Sync.hs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Command/Sync.hs b/Command/Sync.hs index 0c12fa0908..456821b897 100644 --- a/Command/Sync.hs +++ b/Command/Sync.hs @@ -487,6 +487,5 @@ syncFile ebloom rs af k = do ) , return [] ) - put dest = includeCommandAction $ do - showStart' "copy" k af + put dest = includeCommandAction $ Command.Move.toStart' dest False af k