amp 0.5.2 → 0.5.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (232) hide show
  1. data/.gitignore +12 -0
  2. data/.hgignore +3 -0
  3. data/AUTHORS +1 -1
  4. data/Manifest.txt +99 -38
  5. data/README.md +3 -3
  6. data/Rakefile +53 -18
  7. data/SCHEDULE.markdown +5 -1
  8. data/TODO.markdown +120 -149
  9. data/ampfile.rb +3 -1
  10. data/bin/amp +4 -1
  11. data/ext/amp/bz2/extconf.rb +1 -1
  12. data/ext/amp/mercurial_patch/extconf.rb +1 -1
  13. data/ext/amp/mercurial_patch/mpatch.c +4 -3
  14. data/ext/amp/priority_queue/extconf.rb +1 -1
  15. data/ext/amp/support/extconf.rb +1 -1
  16. data/ext/amp/support/support.c +1 -1
  17. data/lib/amp.rb +125 -67
  18. data/lib/amp/commands/command.rb +12 -10
  19. data/lib/amp/commands/command_support.rb +8 -1
  20. data/lib/amp/commands/commands/help.rb +2 -20
  21. data/lib/amp/commands/commands/init.rb +14 -2
  22. data/lib/amp/commands/commands/templates.rb +6 -4
  23. data/lib/amp/commands/commands/version.rb +15 -1
  24. data/lib/amp/commands/commands/workflow.rb +3 -3
  25. data/lib/amp/commands/commands/workflows/git/add.rb +3 -3
  26. data/lib/amp/commands/commands/workflows/git/copy.rb +1 -1
  27. data/lib/amp/commands/commands/workflows/git/rm.rb +4 -2
  28. data/lib/amp/commands/commands/workflows/hg/add.rb +1 -1
  29. data/lib/amp/commands/commands/workflows/hg/addremove.rb +2 -2
  30. data/lib/amp/commands/commands/workflows/hg/annotate.rb +8 -2
  31. data/lib/amp/commands/commands/workflows/hg/bisect.rb +253 -0
  32. data/lib/amp/commands/commands/workflows/hg/branch.rb +1 -1
  33. data/lib/amp/commands/commands/workflows/hg/branches.rb +3 -3
  34. data/lib/amp/commands/commands/workflows/hg/bundle.rb +3 -3
  35. data/lib/amp/commands/commands/workflows/hg/clone.rb +4 -5
  36. data/lib/amp/commands/commands/workflows/hg/commit.rb +37 -1
  37. data/lib/amp/commands/commands/workflows/hg/copy.rb +2 -1
  38. data/lib/amp/commands/commands/workflows/hg/debug/index.rb +1 -1
  39. data/lib/amp/commands/commands/workflows/hg/diff.rb +3 -8
  40. data/lib/amp/commands/commands/workflows/hg/forget.rb +5 -4
  41. data/lib/amp/commands/commands/workflows/hg/identify.rb +6 -6
  42. data/lib/amp/commands/commands/workflows/hg/import.rb +1 -1
  43. data/lib/amp/commands/commands/workflows/hg/incoming.rb +2 -2
  44. data/lib/amp/commands/commands/workflows/hg/log.rb +5 -4
  45. data/lib/amp/commands/commands/workflows/hg/merge.rb +1 -1
  46. data/lib/amp/commands/commands/workflows/hg/move.rb +5 -3
  47. data/lib/amp/commands/commands/workflows/hg/outgoing.rb +1 -1
  48. data/lib/amp/commands/commands/workflows/hg/push.rb +6 -7
  49. data/lib/amp/commands/commands/workflows/hg/remove.rb +2 -2
  50. data/lib/amp/commands/commands/workflows/hg/resolve.rb +6 -23
  51. data/lib/amp/commands/commands/workflows/hg/root.rb +1 -2
  52. data/lib/amp/commands/commands/workflows/hg/status.rb +21 -12
  53. data/lib/amp/commands/commands/workflows/hg/tag.rb +2 -2
  54. data/lib/amp/commands/commands/workflows/hg/untrack.rb +12 -0
  55. data/lib/amp/commands/commands/workflows/hg/verify.rb +13 -3
  56. data/lib/amp/commands/commands/workflows/hg/what_changed.rb +18 -0
  57. data/lib/amp/commands/dispatch.rb +12 -13
  58. data/lib/amp/dependencies/amp_support.rb +1 -1
  59. data/lib/amp/dependencies/amp_support/ruby_amp_support.rb +1 -0
  60. data/lib/amp/dependencies/maruku.rb +136 -0
  61. data/lib/amp/dependencies/maruku/attributes.rb +227 -0
  62. data/lib/amp/dependencies/maruku/defaults.rb +71 -0
  63. data/lib/amp/dependencies/maruku/errors_management.rb +92 -0
  64. data/lib/amp/dependencies/maruku/helpers.rb +260 -0
  65. data/lib/amp/dependencies/maruku/input/charsource.rb +326 -0
  66. data/lib/amp/dependencies/maruku/input/extensions.rb +69 -0
  67. data/lib/amp/dependencies/maruku/input/html_helper.rb +189 -0
  68. data/lib/amp/dependencies/maruku/input/linesource.rb +111 -0
  69. data/lib/amp/dependencies/maruku/input/parse_block.rb +615 -0
  70. data/lib/amp/dependencies/maruku/input/parse_doc.rb +234 -0
  71. data/lib/amp/dependencies/maruku/input/parse_span_better.rb +746 -0
  72. data/lib/amp/dependencies/maruku/input/rubypants.rb +225 -0
  73. data/lib/amp/dependencies/maruku/input/type_detection.rb +147 -0
  74. data/lib/amp/dependencies/maruku/input_textile2/t2_parser.rb +163 -0
  75. data/lib/amp/dependencies/maruku/maruku.rb +33 -0
  76. data/lib/amp/dependencies/maruku/output/to_ansi.rb +223 -0
  77. data/lib/amp/dependencies/maruku/output/to_html.rb +991 -0
  78. data/lib/amp/dependencies/maruku/output/to_markdown.rb +164 -0
  79. data/lib/amp/dependencies/maruku/output/to_s.rb +56 -0
  80. data/lib/amp/dependencies/maruku/string_utils.rb +191 -0
  81. data/lib/amp/dependencies/maruku/structures.rb +167 -0
  82. data/lib/amp/dependencies/maruku/structures_inspect.rb +87 -0
  83. data/lib/amp/dependencies/maruku/structures_iterators.rb +61 -0
  84. data/lib/amp/dependencies/maruku/textile2.rb +1 -0
  85. data/lib/amp/dependencies/maruku/toc.rb +199 -0
  86. data/lib/amp/dependencies/maruku/usage/example1.rb +33 -0
  87. data/lib/amp/dependencies/maruku/version.rb +40 -0
  88. data/lib/amp/dependencies/priority_queue.rb +2 -1
  89. data/lib/amp/dependencies/python_config.rb +2 -1
  90. data/lib/amp/graphs/ancestor.rb +2 -1
  91. data/lib/amp/graphs/copies.rb +236 -233
  92. data/lib/amp/help/entries/__default__.erb +31 -0
  93. data/lib/amp/help/entries/commands.erb +6 -0
  94. data/lib/amp/help/entries/mdtest.md +35 -0
  95. data/lib/amp/help/entries/silly +3 -0
  96. data/lib/amp/help/help.rb +288 -0
  97. data/lib/amp/profiling_hacks.rb +5 -3
  98. data/lib/amp/repository/abstract/abstract_changeset.rb +97 -0
  99. data/lib/amp/repository/abstract/abstract_local_repo.rb +181 -0
  100. data/lib/amp/repository/abstract/abstract_staging_area.rb +180 -0
  101. data/lib/amp/repository/abstract/abstract_versioned_file.rb +100 -0
  102. data/lib/amp/repository/abstract/common_methods/changeset.rb +75 -0
  103. data/lib/amp/repository/abstract/common_methods/local_repo.rb +277 -0
  104. data/lib/amp/repository/abstract/common_methods/staging_area.rb +233 -0
  105. data/lib/amp/repository/abstract/common_methods/versioned_file.rb +71 -0
  106. data/lib/amp/repository/generic_repo_picker.rb +78 -0
  107. data/lib/amp/repository/git/repo_format/changeset.rb +336 -0
  108. data/lib/amp/repository/git/repo_format/staging_area.rb +192 -0
  109. data/lib/amp/repository/git/repo_format/versioned_file.rb +119 -0
  110. data/lib/amp/repository/git/repositories/local_repository.rb +164 -0
  111. data/lib/amp/repository/git/repository.rb +41 -0
  112. data/lib/amp/repository/mercurial/encoding/mercurial_diff.rb +382 -0
  113. data/lib/amp/repository/mercurial/encoding/mercurial_patch.rb +1 -0
  114. data/lib/amp/repository/mercurial/encoding/patch.rb +294 -0
  115. data/lib/amp/repository/mercurial/encoding/pure_ruby/ruby_mercurial_patch.rb +124 -0
  116. data/lib/amp/repository/mercurial/merging/merge_ui.rb +327 -0
  117. data/lib/amp/repository/mercurial/merging/simple_merge.rb +452 -0
  118. data/lib/amp/repository/mercurial/repo_format/branch_manager.rb +266 -0
  119. data/lib/amp/repository/mercurial/repo_format/changeset.rb +768 -0
  120. data/lib/amp/repository/mercurial/repo_format/dir_state.rb +716 -0
  121. data/lib/amp/repository/mercurial/repo_format/journal.rb +218 -0
  122. data/lib/amp/repository/mercurial/repo_format/lock.rb +210 -0
  123. data/lib/amp/repository/mercurial/repo_format/merge_state.rb +228 -0
  124. data/lib/amp/repository/mercurial/repo_format/staging_area.rb +367 -0
  125. data/lib/amp/repository/mercurial/repo_format/store.rb +487 -0
  126. data/lib/amp/repository/mercurial/repo_format/tag_manager.rb +322 -0
  127. data/lib/amp/repository/mercurial/repo_format/updatable.rb +543 -0
  128. data/lib/amp/repository/mercurial/repo_format/updater.rb +848 -0
  129. data/lib/amp/repository/mercurial/repo_format/verification.rb +433 -0
  130. data/lib/amp/repository/mercurial/repositories/bundle_repository.rb +216 -0
  131. data/lib/amp/repository/mercurial/repositories/http_repository.rb +386 -0
  132. data/lib/amp/repository/mercurial/repositories/local_repository.rb +2034 -0
  133. data/lib/amp/repository/mercurial/repository.rb +119 -0
  134. data/lib/amp/repository/mercurial/revlogs/bundle_revlogs.rb +249 -0
  135. data/lib/amp/repository/mercurial/revlogs/changegroup.rb +217 -0
  136. data/lib/amp/repository/mercurial/revlogs/changelog.rb +339 -0
  137. data/lib/amp/repository/mercurial/revlogs/file_log.rb +152 -0
  138. data/lib/amp/repository/mercurial/revlogs/index.rb +500 -0
  139. data/lib/amp/repository/mercurial/revlogs/manifest.rb +201 -0
  140. data/lib/amp/repository/mercurial/revlogs/node.rb +20 -0
  141. data/lib/amp/repository/mercurial/revlogs/revlog.rb +1026 -0
  142. data/lib/amp/repository/mercurial/revlogs/revlog_support.rb +129 -0
  143. data/lib/amp/repository/mercurial/revlogs/versioned_file.rb +597 -0
  144. data/lib/amp/repository/repository.rb +11 -88
  145. data/lib/amp/server/extension/amp_extension.rb +3 -3
  146. data/lib/amp/server/fancy_http_server.rb +1 -1
  147. data/lib/amp/server/fancy_views/_browser.haml +1 -1
  148. data/lib/amp/server/fancy_views/_diff_file.haml +1 -8
  149. data/lib/amp/server/fancy_views/changeset.haml +2 -2
  150. data/lib/amp/server/fancy_views/file.haml +1 -1
  151. data/lib/amp/server/fancy_views/file_diff.haml +1 -1
  152. data/lib/amp/support/amp_ui.rb +13 -29
  153. data/lib/amp/support/generator.rb +1 -1
  154. data/lib/amp/support/loaders.rb +1 -2
  155. data/lib/amp/support/logger.rb +10 -16
  156. data/lib/amp/support/match.rb +18 -4
  157. data/lib/amp/support/mercurial/ignore.rb +151 -0
  158. data/lib/amp/support/openers.rb +8 -3
  159. data/lib/amp/support/support.rb +91 -46
  160. data/lib/amp/templates/{blank.commit.erb → mercurial/blank.commit.erb} +0 -0
  161. data/lib/amp/templates/{blank.log.erb → mercurial/blank.log.erb} +0 -0
  162. data/lib/amp/templates/{default.commit.erb → mercurial/default.commit.erb} +0 -0
  163. data/lib/amp/templates/{default.log.erb → mercurial/default.log.erb} +0 -0
  164. data/lib/amp/templates/template.rb +18 -18
  165. data/man/amp.1 +51 -0
  166. data/site/src/about/commands.haml +1 -1
  167. data/site/src/css/amp.css +1 -1
  168. data/site/src/index.haml +3 -3
  169. data/tasks/man.rake +39 -0
  170. data/tasks/stats.rake +1 -10
  171. data/tasks/yard.rake +1 -50
  172. data/test/dirstate_tests/test_dir_state.rb +10 -8
  173. data/test/functional_tests/annotate.out +31 -0
  174. data/test/functional_tests/test_functional.rb +155 -63
  175. data/test/localrepo_tests/ampfile.rb +12 -0
  176. data/test/localrepo_tests/test_local_repo.rb +56 -57
  177. data/test/manifest_tests/test_manifest.rb +3 -5
  178. data/test/merge_tests/test_merge.rb +3 -3
  179. data/test/revlog_tests/test_revlog.rb +14 -6
  180. data/test/store_tests/test_fncache_store.rb +19 -19
  181. data/test/test_19_compatibility.rb +46 -0
  182. data/test/test_base85.rb +2 -2
  183. data/test/test_bdiff.rb +2 -2
  184. data/test/test_changegroup.rb +59 -0
  185. data/test/test_commands.rb +2 -2
  186. data/test/test_difflib.rb +2 -2
  187. data/test/test_generator.rb +34 -0
  188. data/test/test_ignore.rb +203 -0
  189. data/test/test_journal.rb +18 -13
  190. data/test/test_match.rb +2 -2
  191. data/test/test_mdiff.rb +3 -3
  192. data/test/test_mpatch.rb +3 -3
  193. data/test/test_multi_io.rb +40 -0
  194. data/test/test_support.rb +18 -2
  195. data/test/test_templates.rb +38 -0
  196. data/test/test_ui.rb +79 -0
  197. data/test/testutilities.rb +56 -0
  198. metadata +168 -49
  199. data/ext/amp/bz2/mkmf.log +0 -38
  200. data/lib/amp/encoding/mercurial_diff.rb +0 -378
  201. data/lib/amp/encoding/mercurial_patch.rb +0 -1
  202. data/lib/amp/encoding/patch.rb +0 -292
  203. data/lib/amp/encoding/pure_ruby/ruby_mercurial_patch.rb +0 -123
  204. data/lib/amp/merges/merge_state.rb +0 -164
  205. data/lib/amp/merges/merge_ui.rb +0 -322
  206. data/lib/amp/merges/simple_merge.rb +0 -450
  207. data/lib/amp/repository/branch_manager.rb +0 -234
  208. data/lib/amp/repository/dir_state.rb +0 -950
  209. data/lib/amp/repository/journal.rb +0 -203
  210. data/lib/amp/repository/lock.rb +0 -207
  211. data/lib/amp/repository/repositories/bundle_repository.rb +0 -214
  212. data/lib/amp/repository/repositories/http_repository.rb +0 -377
  213. data/lib/amp/repository/repositories/local_repository.rb +0 -2661
  214. data/lib/amp/repository/store.rb +0 -485
  215. data/lib/amp/repository/tag_manager.rb +0 -319
  216. data/lib/amp/repository/updatable.rb +0 -532
  217. data/lib/amp/repository/verification.rb +0 -431
  218. data/lib/amp/repository/versioned_file.rb +0 -475
  219. data/lib/amp/revlogs/bundle_revlogs.rb +0 -246
  220. data/lib/amp/revlogs/changegroup.rb +0 -217
  221. data/lib/amp/revlogs/changelog.rb +0 -338
  222. data/lib/amp/revlogs/changeset.rb +0 -521
  223. data/lib/amp/revlogs/file_log.rb +0 -165
  224. data/lib/amp/revlogs/index.rb +0 -493
  225. data/lib/amp/revlogs/manifest.rb +0 -195
  226. data/lib/amp/revlogs/node.rb +0 -18
  227. data/lib/amp/revlogs/revlog.rb +0 -1045
  228. data/lib/amp/revlogs/revlog_support.rb +0 -126
  229. data/lib/amp/support/ignore.rb +0 -144
  230. data/site/Rakefile +0 -38
  231. data/test/test_amp.rb +0 -9
  232. data/test/test_helper.rb +0 -15
@@ -0,0 +1,192 @@
1
+ module Amp
2
+ module Repositories
3
+ module Git
4
+ class StagingArea < Amp::Repositories::AbstractStagingArea
5
+
6
+ attr_accessor :repo
7
+ attr_accessor :vcs_dir
8
+
9
+ def initialize(repo)
10
+ @repo = repo
11
+ @vcs_dir = '.git'
12
+ end
13
+
14
+ ##
15
+ # Marks a file to be added to the repository upon the next commit.
16
+ #
17
+ # @param [[String]] filenames a list of files to add in the next commit
18
+ # @return [Boolean] true for success, false for failure
19
+ def add(*filenames)
20
+ `git add #{filenames.join ' '} 2> /dev/null`
21
+ true
22
+ end
23
+
24
+ ##
25
+ # Marks a file to be removed from the repository upon the next commit. Last argument
26
+ # can be a hash, which can take an :unlink key, specifying whether the files should actually
27
+ # be removed or not.
28
+ #
29
+ # @param [String, Array<String>] filenames a list of files to remove in the next commit
30
+ # @return [Boolean] true for success, false for failure
31
+ def remove(*filenames)
32
+ `git rm #{filenames.join ' '} 2> /dev/null`
33
+ true
34
+ end
35
+
36
+ ##
37
+ # Set +file+ as normal and clean. Un-removes any files marked as removed, and
38
+ # un-adds any files marked as added.
39
+ #
40
+ # @param [String, Array<String>] files the name of the files to mark as normal
41
+ # @return [Boolean] success marker
42
+ def normal(*files)
43
+ # Do nothing...
44
+ true
45
+ end
46
+
47
+ ##
48
+ # Mark the files as untracked.
49
+ #
50
+ # @param [Array<String>] files the name of the files to mark as untracked
51
+ # @return [Boolean] success marker
52
+ def forget(*files)
53
+ `git rm --cached #{files.join ' '} 2> /dev/null`
54
+ true
55
+ end
56
+
57
+ ##
58
+ # Marks a file to be copied from the +from+ location to the +to+ location
59
+ # in the next commit, while retaining history.
60
+ #
61
+ # @param [String] from the source of the file copy
62
+ # @param [String] to the destination of the file copy
63
+ # @return [Boolean] true for success, false for failure
64
+ def copy(from, to)
65
+ `git cp #{from} #{to} 2> /dev/null`
66
+ true
67
+ end
68
+
69
+ ##
70
+ # Marks a file to be moved from the +from+ location to the +to+ location
71
+ # in the next commit, while retaining history.
72
+ #
73
+ # @param [String] from the source of the file move
74
+ # @param [String] to the destination of the file move
75
+ # @return [Boolean] true for success, false for failure
76
+ def move(from, to)
77
+ `git mv #{from} #{to} 2> /dev/null`
78
+ true
79
+ end
80
+
81
+ ##
82
+ # Marks a modified file to be included in the next commit.
83
+ # If your VCS does this implicitly, this should be defined as a no-op.
84
+ #
85
+ # @param [String, Array<String>] filenames a list of files to include for committing
86
+ # @return [Boolean] true for success, false for failure
87
+ def include(*filenames)
88
+ add filenames
89
+ end
90
+ alias_method :stage, :include
91
+
92
+ ##
93
+ # Mark a modified file to not be included in the next commit.
94
+ # If your VCS does not include this idea because staging a file is implicit, this should
95
+ # be defined as a no-op.
96
+ #
97
+ # @param [[String]] filenames a list of files to remove from the staging area for committing
98
+ # @return [Boolean] true for success, false for failure
99
+ def exclude(*filenames)
100
+ `git rm --cached #{filenames.join ' '} 2> /dev/null`
101
+ true
102
+ end
103
+ alias_method :unstage, :exclude
104
+
105
+ ##
106
+ # Returns a Symbol.
107
+ #
108
+ # If you call localrepo#status from this method... well...
109
+ # I DARE YOU!
110
+ def file_status(filename)
111
+ parse!
112
+ inverted = @status.inject({}) do |h, (k, v)|
113
+ v.each {|v_| h[v_] = k }
114
+ h
115
+ end
116
+
117
+ # lame hack, i know
118
+ case val = inverted[filename]
119
+ when :modified
120
+ :normal
121
+ else
122
+ val
123
+ end
124
+ end
125
+
126
+ # modified, lookup, or clean
127
+ # in this case, since we're shelling out,
128
+ # only modified or clean
129
+ def file_precise_status(filename, st)
130
+ parse!
131
+ inverted = @status.inject({}) do |h, (k, v)|
132
+ v.each {|v_| h[v_] = k }
133
+ h
134
+ end
135
+
136
+ # bleh this code sucks
137
+ if inverted[filename] == :modified
138
+ :modified
139
+ else
140
+ :clean
141
+ end
142
+ end
143
+
144
+ ##
145
+ # Calculates the difference (in bytes) between a file and its last tracked state.
146
+ #
147
+ # Supplements the built-in #status method so that its output will include deltas.
148
+ #
149
+ # @apioptional
150
+ # @param [String] file the filename to look up
151
+ # @param [File::Stats] st the current results of File.lstat(file)
152
+ # @return [Fixnum] the number of bytes difference between the file and
153
+ # its last tracked state.
154
+ def calculate_delta(file, st)
155
+ 0
156
+ end
157
+
158
+ def parse!
159
+ return if @parsed
160
+
161
+ @status = {}
162
+ data = `git status 2> /dev/null`.split("\n")
163
+ data.inject @status do |h, line|
164
+ case line
165
+ when /^#\s+(\w+):\s(.+)$/
166
+ h[$1.to_sym] = $2.strip
167
+ when /^#\s+new file:\s(.+)$/
168
+ h[:added] = $1.strip
169
+ when /^#\s+([^ ]+)$/
170
+ h[:untracked] = $1.strip
171
+ else
172
+ h
173
+ end
174
+ end
175
+
176
+ @parsed = true
177
+ end
178
+
179
+ ##
180
+ # Returns all files tracked by the repository *for the working directory* - not
181
+ # to be confused with the most recent changeset.
182
+ #
183
+ # @api
184
+ # @return [Array<String>] all files tracked by the repository at this moment in
185
+ # time, including just-added files (for example) that haven't been committed yet.
186
+ def all_files
187
+ Amp::Git::WorkingDirectoryChangeset.new(@repo).all_files
188
+ end
189
+ end
190
+ end
191
+ end
192
+ end
@@ -0,0 +1,119 @@
1
+ module Amp
2
+ module Git
3
+
4
+ ##
5
+ # This class allows you to access a file at a given revision in the repo's
6
+ # history. You can compare them, sort them, access the changeset, and
7
+ # all sorts of stuff.
8
+ class VersionedFile < Amp::Repositories::AbstractVersionedFile
9
+
10
+ attr_accessor :revision
11
+ attr_accessor :path
12
+ attr_accessor :repo
13
+
14
+ def initialize(repo, path, opts={})
15
+ @repo = repo
16
+ @path = path
17
+ @revision = opts[:revision]
18
+ end
19
+
20
+ ##
21
+ # The changeset to which this versioned file belongs.
22
+ #
23
+ # @return [AbstractChangeset]
24
+ def changeset
25
+ @changeset ||= Changeset.new @repo, @revision
26
+ end
27
+
28
+ ##
29
+ # The size of this file
30
+ #
31
+ # @return [Integer]
32
+ def size
33
+ @size ||= data.size
34
+ end
35
+
36
+ ##
37
+ # The contents of a file at the given revision
38
+ #
39
+ # @return [String] the data at the current revision
40
+ def data
41
+ @data ||= `git show #{revision}:#{path} 2> /dev/null`
42
+ end
43
+
44
+ ##
45
+ # The hash value for sticking this fucker in a hash.
46
+ #
47
+ # @return [Integer]
48
+ def hash
49
+ "#{size}--#{path}--#{repo.root}--#{revision} 2> /dev/null".hash
50
+ end
51
+
52
+ ##
53
+ # Has this file been renamed? If so, return some useful info
54
+ def renamed?
55
+ nil
56
+ end
57
+
58
+ ##
59
+ # Compares to either a bit of text or another versioned file.
60
+ # Returns true if different, false for the same.
61
+ # (much like <=> == 0 for the same)
62
+ #
63
+ # @param [AbstractVersionedFile, String] item what we're being compared to
64
+ # @return [Boolean] true if different, false if same.
65
+ def cmp(item)
66
+ return data == item if item.is_a? String
67
+
68
+ not (data == item.data &&
69
+ size == item.size &&
70
+ revision == item.revision &&
71
+ repo.root == item.repo.root )
72
+ end
73
+
74
+ ##
75
+ # Are two versioned files the same? This means same path and revision indexes.
76
+ #
77
+ # @param [AbstractVersionedFile] vfile what we're being compared to
78
+ # @return [Boolean]
79
+ def ==(vfile)
80
+ !cmp(vfile)
81
+ end
82
+
83
+ ##
84
+ # Gets the flags for this file ('x', 'l', or '')
85
+ #
86
+ # @return [String] 'x', 'l', or ''
87
+ def flags
88
+ '' # because git doesn't track them
89
+ end
90
+
91
+ end
92
+
93
+ ##
94
+ # This is a VersionedFile, except it's in the working directory, so its data
95
+ # is stored on disk in the actual file. Other than that, it's basically the
96
+ # same in its interface!
97
+ class VersionedWorkingFile < VersionedFile
98
+
99
+ ##
100
+ # Initializes a new working dir file - slightly different semantics here
101
+ def initialize(repo, path, opts={})
102
+ super(repo, path, opts)
103
+ end
104
+
105
+ def size
106
+ File.stat(repo.join(path)).size
107
+ end
108
+
109
+ def data
110
+ File.read repo.working_join(path)
111
+ end
112
+
113
+ def changeset
114
+ WorkingDirectoryChangeset.new repo
115
+ end
116
+
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,164 @@
1
+ module Amp
2
+ module Repositories
3
+ module Git
4
+
5
+ class LocalRepository < Amp::Repositories::AbstractLocalRepository
6
+
7
+ attr_accessor :root
8
+ attr_accessor :config
9
+ attr_accessor :file_opener
10
+ attr_accessor :git_opener
11
+ attr_accessor :staging_area
12
+
13
+ def initialize(path="", create=false, config=nil)
14
+ super(path, create, config)
15
+
16
+ @config = config
17
+
18
+ @file_opener = Amp::Opener.new @root # This will open relative to the repo root
19
+ @file_opener.default = :open_file # these two are the same, pretty much
20
+ @git_opener = Amp::Opener.new @root # this will open relative to root/.git
21
+ @git_opener.default = :open_git # just with different defaults
22
+
23
+ @staging_area = Amp::Repositories::Git::StagingArea.new self
24
+
25
+ if create
26
+ init
27
+ end
28
+ end
29
+
30
+ def init(config=@config)
31
+ super(config)
32
+
33
+ `cd #{@root} && git init 2> /dev/null`
34
+ true
35
+ end
36
+
37
+ def commit(opts={})
38
+ add_all_files
39
+ string = "git commit #{opts[:user] ? "--author #{opts[:user].inspect}" : "" }" +
40
+ " #{opts[:empty_ok] ? "--allow-empty" : "" }" +
41
+ " #{opts[:message] ? "-m #{opts[:message].inspect}" : "" } 2> /dev/null"
42
+ string.strip!
43
+
44
+ system string
45
+ end
46
+
47
+ def add_all_files
48
+ staging_area.add status[:modified]
49
+ end
50
+
51
+ def forget(*files)
52
+ staging_area.forget *files
53
+ end
54
+
55
+ def [](rev)
56
+ case rev
57
+ when String
58
+ Amp::Git::Changeset.new self, rev
59
+ when nil
60
+ Amp::Git::WorkingDirectoryChangeset.new self
61
+ when 'tip', :tip
62
+ Amp::Git::Changeset.new self, parents[0]
63
+ when Integer
64
+ revs = `git log --pretty=oneline 2> /dev/null`.split("\n")
65
+ short_name = revs[revs.size - 1 - rev].split(' ').first
66
+ Amp::Git::Changeset.new self, short_name
67
+ end
68
+ end
69
+
70
+ def size
71
+ `git log --pretty=oneline 2> /dev/null`.split("\n").size
72
+ end
73
+
74
+ ##
75
+ # Write +text+ to +filename+, where +filename+
76
+ # is local to the root.
77
+ #
78
+ # @param [String] filename The file as relative to the root
79
+ # @param [String] text The text to write to said file
80
+ def working_write(filename, text)
81
+ file_opener.open filename, 'w' do |f|
82
+ f.write text
83
+ end
84
+ end
85
+
86
+ ##
87
+ # Determines if a file has been modified from :node1 to :node2.
88
+ #
89
+ # @return [Boolean] has it been modified
90
+ def file_modified?(file, opts={})
91
+ file_status(file, opts) == :included
92
+ end
93
+
94
+ ##
95
+ # Returns a Symbol.
96
+ # Possible results:
97
+ # :added (subset of :included)
98
+ # :removed
99
+ # :untracked
100
+ # :included (aka :modified)
101
+ # :normal
102
+ #
103
+ # If you call localrepo#status from this method... well...
104
+ # I DARE YOU!
105
+ def file_status(filename, opts={})
106
+ parse_status! opts
107
+ inverted = @status.inject({}) do |h, (k, v)|
108
+ v.each {|v_| h[v_] = k }
109
+ h
110
+ end
111
+
112
+ # Now convert it so it uses the same jargon
113
+ # we REALLY need to get the dirstate and localrepo on
114
+ # the same page here.
115
+ case inverted[filename]
116
+ when :modified
117
+ :included
118
+ when :added
119
+ :added
120
+ when :removed
121
+ :removed
122
+ when :unknown
123
+ :untracked
124
+ else
125
+ :normal
126
+ end
127
+
128
+ end
129
+
130
+ def parse_status!(opts={})
131
+ return if @parsed
132
+
133
+ data = `git status #{opts[:node1]}..#{opts[:node2]} 2> /dev/null`.split("\n")
134
+ @status = data.inject({}) do |h, line| # yeah i know stfu
135
+ case line
136
+ when /^#\s+(\w+):\s(.+)$/
137
+ h[$1.to_sym] = $2; h
138
+ when /^#\s+([^ ]+)$/
139
+ h[:unknown] = $1; h
140
+ else
141
+ h
142
+ end
143
+ end
144
+ @parsed = true
145
+ end
146
+
147
+ def parents
148
+ first = `git log -1 HEAD 2> /dev/null`
149
+ dad = first[/^commit (.+)$/, 1]
150
+ dad = dad ? dad[0..6] : nil
151
+ mom = nil
152
+
153
+ if first =~ /Merge: (.+)\.\.\. (.+)\.\.\.$/ # Merge: 1c002dd... 35cfb2b...
154
+ dad = $1 # just have them both use the short name, nbd
155
+ mom = $2
156
+ end
157
+
158
+ [dad, mom]
159
+ end
160
+
161
+ end
162
+ end
163
+ end
164
+ end