1 % Copyright (C) 2003-2004 David Roundy
3 % This program is free software; you can redistribute it and/or modify
4 % it under the terms of the GNU General Public License as published by
5 % the Free Software Foundation; either version 2, or (at your option)
8 % This program is distributed in the hope that it will be useful,
9 % but WITHOUT ANY WARRANTY; without even the implied warranty of
10 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 % GNU General Public License for more details.
13 % You should have received a copy of the GNU General Public License
14 % along with this program; see the file COPYING. If not, write to
15 % the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 % Boston, MA 02110-1301, USA.
18 \subsection{darcs tag}
20 module Darcs.Commands.Tag ( tag ) where
21 import Control.Monad ( when )
24 import Darcs.Arguments
25 import Darcs.Hopefully ( n2pia )
26 import Darcs.Repository ( amInRepository, withRepoLock, ($-), read_repo,
27 tentativelyAddPatch, finalizeRepositoryChanges,
29 import Darcs.Repository.Checkpoint ( write_recorded_checkpoint )
31 import Darcs.Patch.Info
32 import Darcs.Patch.Depends
33 import Darcs.Commands.Record ( get_date, get_log )
34 import Darcs.Ordered ( FL(..) )
35 import Darcs.Lock ( world_readable_temp )
36 import Darcs.Flags ( DarcsFlag(..) )
37 import System.IO ( hPutStr, stderr )
40 tag_description :: String
42 "Tag the contents of the repository with a version name."
47 \haskell{tag_help} Tag differs from record in that it doesn't record any
48 new changes, and it always depends on all patches residing in the
49 repository when it is tagged. This means that one can later reproduce this
50 version of the repository by calling, for example:
52 % darcs get --tag "darcs 3.14" REPOLOCATION
58 "Tag is used to name a version of this repository (i.e. the whole tree).\n"
62 tag = DarcsCommand {command_name = "tag",
63 command_help = tag_help,
64 command_description = tag_description,
65 command_extra_args = -1,
66 command_extra_arg_help = ["[TAGNAME]"],
67 command_command = tag_cmd,
68 command_prereq = amInRepository,
69 command_get_arg_possibilities = return [],
70 command_argdefaults = nodefaults,
71 command_advanced_options = [nocompress,umask_option],
72 command_basic_options = [patchname_option, author,
79 tag_cmd :: [DarcsFlag] -> [String] -> IO ()
80 tag_cmd opts args = withRepoLock opts $- \repository -> do
82 the_author <- get_author opts
83 deps <- get_tags_right `fmap` read_repo repository
84 (name, long_comment) <- get_name_log opts args
85 myinfo <- patchinfo date name the_author long_comment
86 let mypatch = infopatch myinfo identity
87 tentativelyAddPatch repository opts $ n2pia $ adddeps mypatch deps
88 finalizeRepositoryChanges repository
89 when (CheckPoint `elem` opts) $ write_recorded_checkpoint repository myinfo
90 putStrLn $ "Finished tagging patch '"++name++"'"
91 where get_name_log :: [DarcsFlag] -> [String] -> IO (String, [String])
92 get_name_log o a = do let o2 = if null a then o else (add_patch_name o (unwords a))
93 (name, comment, _) <- get_log o2 Nothing (world_readable_temp "darcs-tag") NilFL
94 when (length name < 2) $ hPutStr stderr $
95 "Do you really want to tag '"
96 ++name++"'? If not type: darcs obliterate --last=1\n"
97 return ("TAG " ++ name, comment)
98 add_patch_name :: [DarcsFlag] -> String -> [DarcsFlag]
99 add_patch_name o a| has_patch_name o = o
100 | otherwise = [PatchName a] ++ o
101 has_patch_name (PatchName _:_) = True
102 has_patch_name (_:fs) = has_patch_name fs
103 has_patch_name [] = False
106 Each tagged version has a version name.
107 The version is also flagged with the person who tagged it (taken by default
108 from the `DARCS\_EMAIL' or `EMAIL' environment variable). The date is also
109 included in the version information.
111 A tagged version automatically depends on all patches in the repository. This
112 allows you to later reproduce precisely that version. The tag does this by
113 depending on all patches in the repository, except for those which are depended
114 upon by other tags already in the repository. In the common case of a sequential
115 series of tags, this means that the tag depends on all patches since the
116 last tag, plus that tag itself.
121 The \verb!--checkpoint! option allows the tag be used later with the
122 \verb!--partial! flag to \verb!get! or \verb!check!.
124 A partial repository only contains patches from after the checkpoint. A
125 partial repository works just like a normal repository, but any command that
126 needs to look at the contents of a missing patch will complain and abort.
132 If you run tag with the \verb!--pipe! option, you will be prompted for the
133 tag date and author. This interface is intended for scripting darcs, in
134 particular for writing repository conversion scripts. The prompts are
135 intended mostly as useful guide (since scripts won't need them), to help
136 you understand the format in which to provide the input. Here's an example
137 of what the \verb!--pipe! prompts looks like:
140 What is the date? Mon Nov 15 13:38:01 EST 2004
141 Who is the author? David Roundy
142 What is the version name? 3.0
143 Finished tagging patch 'TAG 3.0'
146 Using \verb!tag! creates an entry in the repository history just like \verb!record!.
147 It will show up with \verb!darcs changes! appearing in the format:
153 To display all tags in the repository, use the ``\verb!darcs query tags!''