summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2013-10-28 16:56:01 -0400
committerGravatar Joey Hess <joey@kitenet.net>2013-10-28 16:56:01 -0400
commit39163cb024b49a0214c104d4fe21b778bbd63eaa (patch)
treed6ff5978d5cac09dac14231a5d423a6784102dfa
parentd93d453c3c4d41d446970db21b1d504b3690adb6 (diff)
unannex: New, much slower, but more safe behavior
Copies files out of the annex. This avoids an unannex of one file breaking other files that link to the same content. Also, it means that the content remains in the annex using up space until cleaned up with "git annex unused". (The behavior of unannex --fast has not changed; it still hard links to content in the annex. --fast was not made the default because it is potentially unsafe; editing such a hard linked file can unexpectedly change content stored in the annex.)
-rw-r--r--Command/Unannex.hs30
-rw-r--r--Command/Uninit.hs10
-rw-r--r--debian/changelog9
-rw-r--r--doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss.mdwn7
-rw-r--r--doc/bugs/Of_identical_files__44___all_but_the_first_copy_are_lost_on_unannex.mdwn2
-rw-r--r--doc/git-annex.mdwn14
6 files changed, 41 insertions, 31 deletions
diff --git a/Command/Unannex.hs b/Command/Unannex.hs
index 66665f494..5e3c4279a 100644
--- a/Command/Unannex.hs
+++ b/Command/Unannex.hs
@@ -13,11 +13,11 @@ import Common.Annex
import Command
import Config
import qualified Annex
-import Logs.Location
import Annex.Content
import Annex.Content.Direct
import qualified Git.Command
import qualified Git.LsFiles as LsFiles
+import Utility.CopyFile
def :: [Command]
def = [command "unannex" paramPaths seek SectionUtility
@@ -60,28 +60,24 @@ performIndirect file key = do
cleanupIndirect :: FilePath -> Key -> CommandCleanup
cleanupIndirect file key = do
+ src <- calcRepo $ gitAnnexLocation key
ifM (Annex.getState Annex.fast)
- ( goFast
- , go
+ ( hardlinkfrom src
+ , copyfrom src
)
- return True
where
-#ifdef mingw32_HOST_OS
- goFast = go
-#else
- goFast = do
- -- fast mode: hard link to content in annex
- src <- calcRepo $ gitAnnexLocation key
- -- creating a hard link could fall; fall back to non fast mode
+ copyfrom src =
+ thawContent file `after` liftIO (copyFileExternal src file)
+ hardlinkfrom src =
+#ifndef mingw32_HOST_OS
+ -- creating a hard link could fall; fall back to copying
ifM (liftIO $ catchBoolIO $ createLink src file >> return True)
- ( thawContent file
- , go
+ ( return True
+ , copyfrom src
)
+#else
+ copyfrom src
#endif
- go = do
- fromAnnex key file
- logStatus key InfoMissing
-
performDirect :: FilePath -> Key -> CommandPerform
performDirect file key = do
diff --git a/Command/Uninit.hs b/Command/Uninit.hs
index a40e28399..f017d196e 100644
--- a/Command/Uninit.hs
+++ b/Command/Uninit.hs
@@ -38,7 +38,7 @@ check = do
seek :: [CommandSeek]
seek =
[ withFilesNotInGit $ whenAnnexed startCheckIncomplete
- , withFilesInGit $ whenAnnexed startUnannex
+ , withFilesInGit $ whenAnnexed Command.Unannex.start
, withNothing start
]
@@ -51,14 +51,6 @@ startCheckIncomplete file _ = error $ unlines
, "Not continuing with uninit; either delete or git annex add the file and retry."
]
-startUnannex :: FilePath -> (Key, Backend) -> CommandStart
-startUnannex file info = do
- -- Force fast mode before running unannex. This way, if multiple
- -- files link to a key, it will be left in the annex and hardlinked
- -- to by each.
- Annex.changeState $ \s -> s { Annex.fast = True }
- Command.Unannex.start file info
-
start :: CommandStart
start = next $ next $ do
annexdir <- fromRepo gitAnnexDir
diff --git a/debian/changelog b/debian/changelog
index e35bb9127..ff6d4095e 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -18,6 +18,15 @@ git-annex (4.20131025) UNRELEASED; urgency=low
(eg, on removable drives).
* add: Fix reversion in 4.20130827 when adding unlocked files that have
not yet been committed.
+ * unannex: New, much slower, but more safe behavior: Copies files out of
+ the annex. This avoids an unannex of one file breaking other files that
+ link to the same content. Also, it means that the content
+ remains in the annex using up space until cleaned up with
+ "git annex unused".
+ (The behavior of unannex --fast has not changed; it still hard links
+ to content in the annex. --fast was not made the default because it is
+ potentially unsafe; editing such a hard linked file can unexpectedly
+ change content stored in the annex.)
-- Joey Hess <joeyh@debian.org> Sat, 26 Oct 2013 12:11:48 -0400
diff --git a/doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss.mdwn b/doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss.mdwn
index 630db722b..2629a7d56 100644
--- a/doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss.mdwn
+++ b/doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss.mdwn
@@ -48,3 +48,10 @@ For this reason, it seems likely this is due to some sort of race condition.
This is on Ubuntu 12.04 with git-annex revision a1e2bc4.
+> There was no good soluton to this, so I picked a bad one that
+> will not have users complainging git-annex ate their data.
+> They will complain that `git annex unannex` is slow since it now copies
+> the file, and perhaps instead use --fast, and hopefully avoid destroying
+> their own data by editing the resulting hard links.
+>
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/Of_identical_files__44___all_but_the_first_copy_are_lost_on_unannex.mdwn b/doc/bugs/Of_identical_files__44___all_but_the_first_copy_are_lost_on_unannex.mdwn
index 8c13a88ac..3860456d2 100644
--- a/doc/bugs/Of_identical_files__44___all_but_the_first_copy_are_lost_on_unannex.mdwn
+++ b/doc/bugs/Of_identical_files__44___all_but_the_first_copy_are_lost_on_unannex.mdwn
@@ -50,3 +50,5 @@ Now file1.txt is a normal 6-byte file again, but 2, 3, and 4 are broken symlinks
git-annex 4.20130802 package
on Debian GNU/Linux jessie/sid (testing), amd64.
+
+> [[dup|done]] --[[Joey]]
diff --git a/doc/git-annex.mdwn b/doc/git-annex.mdwn
index 8d27bd7a7..8ff0b7962 100644
--- a/doc/git-annex.mdwn
+++ b/doc/git-annex.mdwn
@@ -673,16 +673,20 @@ subdirectories).
* `unannex [path ...]`
- Use this to undo an accidental `git annex add` command. You can use
- `git annex unannex` to move content out of the annex at any point,
- even if you've already committed it.
+ Use this to undo an accidental `git annex add` command. It puts the
+ file back how it was before the add.
+
+ Note that for safety, the content of the file remains in the annex (as a
+ hard link), until you use `git annex unused` and `git annex dropunused`.
This is not the command you should use if you intentionally annexed a
file and don't want its contents any more. In that case you should use
`git annex drop` instead, and you can also `git rm` the file.
- In `--fast` mode, this command leaves content in the annex, simply making
- a hard link to it.
+ Normally this does a slow copy of the file. In `--fast` mode, it
+ instead makes a hard link from the file to the content in the annex.
+ But use --fast mode with caution, because editing the file will
+ change the content in the annex.
* `uninit`