summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2014-02-06 12:43:56 -0400
committerGravatar Joey Hess <joey@kitenet.net>2014-02-06 12:43:56 -0400
commitebb16a8c45f5ec12aff6fd158090d6a36d5590dc (patch)
treedf6630b4844709e8266f330a875857d395c03454
parentd6a25390ad9006d3c8eeeefd535703626dd09490 (diff)
--in can now refer to files that were located in a repository at some past date. For example, --in="here@{yesterday}"
-rw-r--r--Annex/Branch.hs9
-rw-r--r--Git/Ref.hs5
-rw-r--r--Git/Types.hs4
-rw-r--r--Limit.hs24
-rw-r--r--Logs/Location.hs16
-rw-r--r--Logs/Presence.hs15
-rw-r--r--debian/changelog2
-rw-r--r--doc/git-annex.mdwn13
8 files changed, 73 insertions, 15 deletions
diff --git a/Annex/Branch.hs b/Annex/Branch.hs
index 391e82ae6..ee3cd71e2 100644
--- a/Annex/Branch.hs
+++ b/Annex/Branch.hs
@@ -18,6 +18,7 @@ module Annex.Branch (
forceUpdate,
updateTo,
get,
+ getHistorical,
change,
commit,
forceCommit,
@@ -197,7 +198,13 @@ getLocal file = go =<< getJournalFileStale file
go Nothing = getRaw file
getRaw :: FilePath -> Annex String
-getRaw file = withIndex $ L.unpack <$> catFile fullname file
+getRaw = getRef fullname
+
+getHistorical :: RefDate -> FilePath -> Annex String
+getHistorical date = getRef (Git.Ref.dateRef fullname date)
+
+getRef :: Ref -> FilePath -> Annex String
+getRef ref file = withIndex $ L.unpack <$> catFile ref file
{- Applies a function to modifiy the content of a file.
-
diff --git a/Git/Ref.hs b/Git/Ref.hs
index 09472930f..88717ce47 100644
--- a/Git/Ref.hs
+++ b/Git/Ref.hs
@@ -11,6 +11,7 @@ import Common
import Git
import Git.Command
import Git.Sha
+import Git.Types
import Data.Char (chr)
@@ -51,6 +52,10 @@ underBase dir r = Ref $ dir ++ "/" ++ show (base r)
fileRef :: FilePath -> Ref
fileRef f = Ref $ ":./" ++ f
+{- Converts a Ref to refer to the content of the Ref on a given date. -}
+dateRef :: Ref -> RefDate -> Ref
+dateRef (Ref r) (RefDate d) = Ref $ r ++ "@" ++ d
+
{- A Ref that can be used to refer to a file in the repository as it
- appears in a given Ref. -}
fileFromRef :: Ref -> FilePath -> Ref
diff --git a/Git/Types.hs b/Git/Types.hs
index e63e93077..d805d8574 100644
--- a/Git/Types.hs
+++ b/Git/Types.hs
@@ -57,6 +57,10 @@ type Branch = Ref
type Sha = Ref
type Tag = Ref
+{- A date in the format described in gitrevisions. Includes the
+ - braces, eg, "{yesterday}" -}
+newtype RefDate = RefDate String
+
{- Types of objects that can be stored in git. -}
data ObjectType = BlobObject | CommitObject | TreeObject
deriving (Eq)
diff --git a/Limit.hs b/Limit.hs
index bc1705bea..6f4101633 100644
--- a/Limit.hs
+++ b/Limit.hs
@@ -30,6 +30,8 @@ import Types.FileMatcher
import Types.Limit
import Logs.Group
import Logs.Unused
+import Logs.Location
+import Git.Types (RefDate(..))
import Utility.HumanTime
import Utility.DataUnits
@@ -112,20 +114,26 @@ matchglob glob (MatchingFile fi) =
matchglob _ (MatchingKey _) = False
{- Adds a limit to skip files not believed to be present
- - in a specfied repository. -}
+ - in a specfied repository. Optionally on a prior date. -}
addIn :: String -> Annex ()
addIn = addLimit . limitIn
limitIn :: MkLimit
-limitIn name = Right $ \notpresent -> checkKey $
+limitIn s = Right $ \notpresent -> checkKey $ \key ->
if name == "."
- then inhere notpresent
- else inremote notpresent
+ then if null date
+ then inhere notpresent key
+ else inuuid notpresent key =<< getUUID
+ else inuuid notpresent key =<< Remote.nameToUUID name
where
- inremote notpresent key = do
- u <- Remote.nameToUUID name
- us <- Remote.keyLocations key
- return $ u `elem` us && u `S.notMember` notpresent
+ (name, date) = separate (== '@') s
+ inuuid notpresent key u
+ | null date = do
+ us <- Remote.keyLocations key
+ return $ u `elem` us && u `S.notMember` notpresent
+ | otherwise = do
+ us <- loggedLocationsHistorical (RefDate date) key
+ return $ u `elem` us
inhere notpresent key
| S.null notpresent = inAnnex key
| otherwise = do
diff --git a/Logs/Location.hs b/Logs/Location.hs
index f751c00de..cb1e415fd 100644
--- a/Logs/Location.hs
+++ b/Logs/Location.hs
@@ -8,7 +8,7 @@
- Repositories record their UUID and the date when they --get or --drop
- a value.
-
- - Copyright 2010-2011 Joey Hess <joey@kitenet.net>
+ - Copyright 2010-2014 Joey Hess <joey@kitenet.net>
-
- Licensed under the GNU GPL version 3 or higher.
-}
@@ -18,6 +18,7 @@ module Logs.Location (
logStatus,
logChange,
loggedLocations,
+ loggedLocationsHistorical,
loggedKeys,
loggedKeysFor,
) where
@@ -27,6 +28,7 @@ import qualified Annex.Branch
import Logs
import Logs.Presence
import Annex.UUID
+import Git.Types (RefDate)
{- Log a change in the presence of a key's value in current repository. -}
logStatus :: Key -> LogStatus -> Annex ()
@@ -40,10 +42,16 @@ logChange key (UUID u) s = addLog (locationLogFile key) =<< logNow s u
logChange _ NoUUID _ = noop
{- Returns a list of repository UUIDs that, according to the log, have
- - the value of a key.
- -}
+ - the value of a key. -}
loggedLocations :: Key -> Annex [UUID]
-loggedLocations key = map toUUID <$> (currentLog . locationLogFile) key
+loggedLocations = getLoggedLocations currentLog
+
+{- Gets the location log on a particular date. -}
+loggedLocationsHistorical :: RefDate -> Key -> Annex [UUID]
+loggedLocationsHistorical = getLoggedLocations . historicalLog
+
+getLoggedLocations :: (FilePath -> Annex [String]) -> Key -> Annex [UUID]
+getLoggedLocations getter key = map toUUID <$> (getter . locationLogFile) key
{- Finds all keys that have location log information.
- (There may be duplicate keys in the list.) -}
diff --git a/Logs/Presence.hs b/Logs/Presence.hs
index 516d59618..7545f5afc 100644
--- a/Logs/Presence.hs
+++ b/Logs/Presence.hs
@@ -6,7 +6,7 @@
- A line of the log will look like: "date N INFO"
- Where N=1 when the INFO is present, and 0 otherwise.
-
- - Copyright 2010-2011 Joey Hess <joey@kitenet.net>
+ - Copyright 2010-2014 Joey Hess <joey@kitenet.net>
-
- Licensed under the GNU GPL version 3 or higher.
-}
@@ -16,7 +16,8 @@ module Logs.Presence (
addLog,
readLog,
logNow,
- currentLog
+ currentLog,
+ historicalLog
) where
import Data.Time.Clock.POSIX
@@ -24,6 +25,7 @@ import Data.Time.Clock.POSIX
import Logs.Presence.Pure as X
import Common.Annex
import qualified Annex.Branch
+import Git.Types (RefDate)
addLog :: FilePath -> LogLine -> Annex ()
addLog file line = Annex.Branch.change file $ \s ->
@@ -43,3 +45,12 @@ logNow s i = do
{- Reads a log and returns only the info that is still in effect. -}
currentLog :: FilePath -> Annex [String]
currentLog file = map info . filterPresent <$> readLog file
+
+{- Reads a historical version of a log and returns the info that was in
+ - effect at that time.
+ -
+ - The date is formatted as shown in gitrevisions man page.
+ -}
+historicalLog :: RefDate -> FilePath -> Annex [String]
+historicalLog refdate file = map info . filterPresent . parseLog
+ <$> Annex.Branch.getHistorical refdate file
diff --git a/debian/changelog b/debian/changelog
index 275bf96b3..5bfb26194 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,5 +1,7 @@
git-annex (5.20140128) UNRELEASED; urgency=medium
+ * --in can now refer to files that were located in a repository at
+ some past date. For example, --in="here@{yesterday}"
* Fixed direct mode annexed content locking code, which is used to
guard against recursive file drops.
* sync --content: Honor annex-ignore configuration.
diff --git a/doc/git-annex.mdwn b/doc/git-annex.mdwn
index 90774a74b..89aef70f6 100644
--- a/doc/git-annex.mdwn
+++ b/doc/git-annex.mdwn
@@ -1005,6 +1005,19 @@ file contents are present at either of two repositories.
or the UUID or description of a repository. For the current repository,
use `--in=here`
+* `--in=repository@{date}`
+
+ Matches files currently in the work tree whose content was present in
+ the repository on the given date.
+
+ The date is specified in the same syntax documented in
+ gitrevisions(7). Note that this uses the reflog, so dates far in the
+ past cannot be queried.
+
+ For example, you might need to run `git annex drop .` to temporarily
+ free up disk space. The next day, you can get back the files you dropped
+ using `git annex get . --in=here@{yesterday}`
+
* `--copies=number`
Matches only files that git-annex believes to have the specified number