summaryrefslogtreecommitdiff
path: root/Command/Proxy.hs
diff options
context:
space:
mode:
authorGravatar Joey Hess <joeyh@joeyh.name>2015-08-04 14:01:59 -0400
committerGravatar Joey Hess <joeyh@joeyh.name>2015-08-04 14:01:59 -0400
commit76bc6f4b653a9dc94709fc3ee511cc877c487ee1 (patch)
treefb7b9bacbb8a99a43d9b6e4cda2a24e6a070e389 /Command/Proxy.hs
parent5c2eff7f4e56378a807f0c5e2a32f1e65d8da0b6 (diff)
proxy: Fix proxy git commit of non-annexed files in direct mode.
* proxy: Fix proxy git commit of non-annexed files in direct mode. * proxy: If a non-proxied git command, such as git revert would normally fail because of unstaged files in the work tree, make the proxied command fail the same way.
Diffstat (limited to 'Command/Proxy.hs')
-rw-r--r--Command/Proxy.hs39
1 files changed, 38 insertions, 1 deletions
diff --git a/Command/Proxy.hs b/Command/Proxy.hs
index 3c487b9b5..97cfafeaf 100644
--- a/Command/Proxy.hs
+++ b/Command/Proxy.hs
@@ -13,9 +13,13 @@ import Config
import Utility.Tmp
import Utility.Env
import Annex.Direct
+import qualified Git
import qualified Git.Sha
import qualified Git.Ref
import qualified Git.Branch
+import qualified Git.LsFiles
+import Git.FilePath
+import Utility.CopyFile
cmd :: Command
cmd = notBareRepo $
@@ -38,12 +42,45 @@ start (c:ps) = liftIO . exitWith =<< ifM isDirect
go tmp = do
oldref <- fromMaybe Git.Sha.emptyTree
<$> inRepo Git.Ref.headSha
+
+ setuptmpworktree tmp
exitcode <- proxy tmp
- mergeDirectCleanup tmp oldref
+ cleanupproxy tmp oldref
+
return exitcode
+
proxy tmp = do
usetmp <- liftIO $ Just . addEntry "GIT_WORK_TREE" tmp <$> getEnvironment
unlessM (isNothing <$> inRepo Git.Branch.current) $
unlessM (liftIO $ boolSystemEnv "git" [Param "checkout", Param "--", Param "."] usetmp) $
error "Failed to set up proxy work tree."
liftIO $ safeSystemEnv c (map Param ps) usetmp
+
+ -- Commands like git revert will fail if there's a file
+ -- in the work tree, or index, that would be overwritten
+ -- by the revert. We want that to also happen when such a command
+ -- is proxied.
+ --
+ -- It suffices to find any files in the real work tree that
+ -- are not in the index, and hard link (or copy) them
+ -- into the tmp work tree. This assumes that files that are in the
+ -- index don't need to appear in the tmp work tree.
+ setuptmpworktree tmp = do
+ top <- fromRepo Git.repoPath
+ (fs, cleanup) <- inRepo $ Git.LsFiles.notInRepo True [top]
+ forM_ fs $ \f -> do
+ tf <- inRepo $ toTopFilePath f
+ let tmpf = tmp </> getTopFilePath tf
+ liftIO $ do
+ createDirectoryIfMissing True (takeDirectory tmpf)
+ createLinkOrCopy f tmpf
+ liftIO $ void cleanup
+
+ -- To merge the changes made by the proxied command into
+ -- the work tree is similar to cleaning up after a
+ -- direct mode merge. But, here we force updates of any
+ -- non-annxed files that were changed by the proxied
+ -- command.
+ cleanupproxy tmp oldref = do
+ updateWorkTree tmp oldref True
+ liftIO $ removeDirectoryRecursive tmp