braid 1.0.22 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +0 -2
  3. data/README.md +48 -0
  4. data/_config.yml +1 -0
  5. data/bin/braid +44 -7
  6. data/braid.gemspec +4 -0
  7. data/config_versions.md +58 -0
  8. data/lib/braid.rb +7 -0
  9. data/lib/braid/command.rb +7 -7
  10. data/lib/braid/commands/add.rb +3 -3
  11. data/lib/braid/commands/diff.rb +7 -14
  12. data/lib/braid/commands/push.rb +10 -4
  13. data/lib/braid/commands/setup.rb +5 -1
  14. data/lib/braid/commands/status.rb +5 -1
  15. data/lib/braid/commands/update.rb +6 -15
  16. data/lib/braid/commands/upgrade_config.rb +56 -0
  17. data/lib/braid/config.rb +166 -27
  18. data/lib/braid/mirror.rb +111 -11
  19. data/lib/braid/operations.rb +51 -35
  20. data/lib/braid/version.rb +1 -1
  21. data/spec/config_spec.rb +2 -2
  22. data/spec/fixtures/shiny-conf-1.0.9-lock/.braids.json +10 -0
  23. data/spec/fixtures/shiny-conf-1.0.9-lock/expected.braids.json +9 -0
  24. data/spec/fixtures/shiny-conf-1.0.9-lock/skit1/layouts/layout.liquid +219 -0
  25. data/spec/fixtures/shiny-conf-1.0.9-lock/skit1/preview.png +0 -0
  26. data/spec/fixtures/shiny-conf-breaking-changes/.braids +14 -0
  27. data/spec/fixtures/shiny-conf-breaking-changes/Spoon-Knife/README.md +9 -0
  28. data/spec/fixtures/shiny-conf-breaking-changes/Spoon-Knife/index.html +20 -0
  29. data/spec/fixtures/shiny-conf-breaking-changes/Spoon-Knife/styles.css +17 -0
  30. data/spec/fixtures/shiny-conf-breaking-changes/expected.braids.json +10 -0
  31. data/spec/fixtures/shiny-conf-breaking-changes/skit1/layouts/layout.liquid +219 -0
  32. data/spec/fixtures/shiny-conf-breaking-changes/skit1/preview.png +0 -0
  33. data/spec/fixtures/shiny-conf-future/.braids.json +10 -0
  34. data/spec/fixtures/shiny-conf-future/skit1/layouts/layout.liquid +219 -0
  35. data/spec/fixtures/shiny-conf-future/skit1/preview.png +0 -0
  36. data/spec/fixtures/shiny-conf-json-old-name/.braids +9 -0
  37. data/spec/fixtures/shiny-conf-json-old-name/expected.braids.json +10 -0
  38. data/spec/fixtures/shiny-conf-json-old-name/skit1/layouts/layout.liquid +219 -0
  39. data/spec/fixtures/shiny-conf-json-old-name/skit1/preview.png +0 -0
  40. data/spec/fixtures/shiny-conf-yaml/.braids +8 -0
  41. data/spec/fixtures/shiny-conf-yaml/expected.braids.json +10 -0
  42. data/spec/fixtures/shiny-conf-yaml/skit1/layouts/layout.liquid +219 -0
  43. data/spec/fixtures/shiny-conf-yaml/skit1/preview.png +0 -0
  44. data/spec/fixtures/shiny/skit-layout.liquid.test +2 -0
  45. data/spec/fixtures/shiny/skit1.test +2 -0
  46. data/spec/fixtures/skit1.1x/layouts/layout.liquid +219 -0
  47. data/spec/integration/adding_spec.rb +82 -34
  48. data/spec/integration/config_versioning_spec.rb +222 -0
  49. data/spec/integration/diff_spec.rb +173 -9
  50. data/spec/integration/integration_helper.rb +23 -5
  51. data/spec/integration/push_spec.rb +57 -4
  52. data/spec/integration/remove_spec.rb +27 -5
  53. data/spec/integration/updating_spec.rb +104 -19
  54. metadata +73 -2
@@ -247,21 +247,6 @@ module Braid
247
247
  true
248
248
  end
249
249
 
250
- # Implies no commit.
251
- def merge_ours(opt)
252
- invoke(:merge, '--allow-unrelated-histories -s ours --no-commit', opt)
253
- true
254
- end
255
-
256
- # Implies no commit.
257
- def merge_subtree(opt)
258
- # TODO which options are needed?
259
- invoke(:merge, '-s subtree --no-commit --no-ff', opt)
260
- true
261
- rescue ShellExecutionError => error
262
- raise MergeError, error.out
263
- end
264
-
265
250
  # Merge three trees (local_treeish should match the current state of the
266
251
  # index) and update the index and working tree.
267
252
  #
@@ -282,17 +267,56 @@ module Braid
282
267
  invoke('ls-files', prefix)
283
268
  end
284
269
 
285
- # Read tree into the index and working tree.
286
- def read_tree_prefix_u(treeish, prefix)
287
- invoke(:read_tree, "--prefix=#{prefix}/ -u", treeish)
288
- true
270
+ class BlobWithMode
271
+ def initialize(hash, mode)
272
+ @hash = hash
273
+ @mode = mode
274
+ end
275
+ attr_reader :hash, :mode
276
+ end
277
+ # Allow the class to be referenced as `git.BlobWithMode`.
278
+ def BlobWithMode
279
+ Git::BlobWithMode
289
280
  end
290
281
 
291
- # Read tree into the index, regardless of the state of the working tree.
292
- # Most useful with a temporary index file.
293
- def read_tree_prefix_i(treeish, prefix)
294
- invoke(:read_tree, "--prefix=#{prefix}/ -i", treeish)
295
- true
282
+ # Get the item at the given path in the given tree. If it's a tree, just
283
+ # return its hash; if it's a blob, return a BlobWithMode object. (This is
284
+ # how we remember the mode for single-file mirrors.)
285
+ def get_tree_item(tree, path)
286
+ if path.nil? || path == ''
287
+ tree
288
+ else
289
+ m = /^([^ ]*) ([^ ]*) ([^\t]*)\t.*$/.match(invoke(:ls_tree, tree, path))
290
+ mode = m[1]
291
+ type = m[2]
292
+ hash = m[3]
293
+ if type == 'tree'
294
+ hash
295
+ elsif type == 'blob'
296
+ return BlobWithMode.new(hash, mode)
297
+ else
298
+ raise ShellExecutionError, 'Tree item is not a tree or a blob'
299
+ end
300
+ end
301
+ end
302
+
303
+ # Add the item (as returned by get_tree_item) to the index at the given
304
+ # path. If update_worktree is true, then update the worktree, otherwise
305
+ # disregard the state of the worktree (most useful with a temporary index
306
+ # file).
307
+ def add_item_to_index(item, path, update_worktree)
308
+ if item.is_a?(BlobWithMode)
309
+ # Our minimum git version is 1.6.0 and the new --cacheinfo syntax
310
+ # wasn't added until 2.0.0.
311
+ invoke(:update_index, '--add', '--cacheinfo', item.mode, item.hash, path)
312
+ if update_worktree
313
+ # XXX If this fails, we've already updated the index.
314
+ invoke(:checkout_index, path)
315
+ end
316
+ else
317
+ # Yes, if path == '', "git read-tree --prefix=/" works. :/
318
+ invoke(:read_tree, "--prefix=#{path}/", update_worktree ? '-u' : '-i', item)
319
+ end
296
320
  end
297
321
 
298
322
  # Read tree into the root of the index. This may not be the preferred way
@@ -317,14 +341,13 @@ module Braid
317
341
  end
318
342
  end
319
343
 
320
- def make_tree_with_subtree(main_content, subtree_path, subtree_content)
344
+ def make_tree_with_item(main_content, item_path, item)
321
345
  with_temporary_index do
322
346
  if main_content
323
347
  read_tree_im(main_content)
324
- rm_r_cached(subtree_path)
348
+ rm_r_cached(item_path)
325
349
  end
326
- # Yes, if subtree_path == '', "git read-tree --prefix=/" works. :/
327
- read_tree_prefix_i(subtree_content, subtree_path)
350
+ add_item_to_index(item, item_path, false)
328
351
  write_tree
329
352
  end
330
353
  end
@@ -349,13 +372,6 @@ module Braid
349
372
  out.split[2]
350
373
  end
351
374
 
352
- def diff_tree(src_tree, dst_tree, prefix = nil)
353
- cmd = "git diff-tree -p --binary #{src_tree} #{dst_tree}"
354
- cmd << " --src-prefix=a/#{prefix}/ --dst-prefix=b/#{prefix}/" if prefix
355
- status, out, err = exec!(cmd)
356
- out
357
- end
358
-
359
375
  def diff_to_stdout(*args)
360
376
  # For now, ignore the exit code. It can be 141 (SIGPIPE) if the user
361
377
  # quits the pager before reading all the output.
@@ -1,3 +1,3 @@
1
1
  module Braid
2
- VERSION = '1.0.22'.freeze
2
+ VERSION = '1.1.0'.freeze
3
3
  end
@@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/test_helper'
2
2
 
3
3
  describe 'Braid::Config, when empty' do
4
4
  before(:each) do
5
- @config = Braid::Config.new('tmp.yml')
5
+ @config = Braid::Config.new({'config_file' => 'tmp.yml'})
6
6
  end
7
7
 
8
8
  after(:each) do
@@ -23,7 +23,7 @@ end
23
23
 
24
24
  describe 'Braid::Config, with one mirror' do
25
25
  before(:each) do
26
- @config = Braid::Config.new('tmp.yml')
26
+ @config = Braid::Config.new({'config_file' => 'tmp.yml'})
27
27
  @mirror = build_mirror
28
28
  @config.add(@mirror)
29
29
  end
@@ -0,0 +1,10 @@
1
+ {
2
+ "skit1": {
3
+ "url": "file:///path/to/braid/spec/fixtures/skit1",
4
+ "remote": "master/braid/skit1",
5
+ "branch": "master",
6
+ "squashed": true,
7
+ "revision": "6d3aeac08f9f4f9689d367fc771f5f1c90496176",
8
+ "lock": "6d3aeac08f9f4f9689d367fc771f5f1c90496176"
9
+ }
10
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "config_version": 1,
3
+ "mirrors": {
4
+ "skit1": {
5
+ "url": "file:///path/to/braid/spec/fixtures/skit1",
6
+ "revision": "6d3aeac08f9f4f9689d367fc771f5f1c90496176"
7
+ }
8
+ }
9
+ }
@@ -0,0 +1,219 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2
+ <html xmlns="http://www.w3.org/1999/xhtml">
3
+ {{ '/feed/atom.xml' | assign_to: 'global_feed' }}
4
+ {{ '/feed/all_comments.xml' | assign_to: 'global_comments_feed' }}
5
+ <head>
6
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
7
+ <title>
8
+ {{ site.title }}
9
+ {% if site.current_section %}
10
+ - {{ site.current_section.name }}
11
+ {% endif %}
12
+ {% if article %}
13
+ - {{ article.title }}
14
+ {% endif %}
15
+ </title>
16
+ <link rel="alternate" type="application/atom+xml" title="{{ site.title }} feed" href="{{ global_feed }}"/>
17
+ <link rel="alternate" type="application/atom+xml" title="{{ site.title }} comments feed" href="{{ global_comments_feed }}"/>
18
+ {{ 'base' | stylesheet }}
19
+ {{ 'app' | javascript }}
20
+ <!--[if IE]>
21
+ {{ 'base_ie' | stylesheet }}
22
+ <![endif]-->
23
+ </head>
24
+
25
+ <body class="fixed orange">
26
+ <script type="text/javascript">loadPreferences()</script>
27
+
28
+ <div id="wrapper">
29
+
30
+ <div id="header" class="clearfix">
31
+ <div id="title" class="clearfix">
32
+ <h1><a href="/">{{ site.title }}</a></h1>
33
+ </div>
34
+ <h2>Sections</h2>
35
+ <ul id="menu">
36
+ {% for section in site.sections %}
37
+ {% if section.articles_count > 0 %}
38
+ {% if section.is_home %}
39
+ <li{% if section.current %} class="selected"{% endif %}>{{ section | link_to_section }}</li>
40
+ {% else %}
41
+ {% if section.is_paged %}
42
+ <li{% if section.current %} class="selected"{% endif %}>{{ section | link_to_section }}</li>
43
+ {% endif %}
44
+ {% endif %}
45
+ {% endif %}
46
+ {% endfor %}
47
+ </ul>
48
+ </div>
49
+
50
+ <div id="contentwrapper" class="clearfix">
51
+
52
+ <div id="content">
53
+
54
+ <div id="innerwrapper">
55
+
56
+ <div class="article">
57
+ <div class="body">
58
+ <h2>Skittlish Tips'n'Tricks</h2>
59
+ <ul>
60
+ <li>Change the classes for the body tag to set your default site style. also change these in the app.js file (line 66).</li>
61
+ <li>Remove the scripts and the #options div if you don't want the option switcher.</li>
62
+ <li>The top menu shows the home section and the sections that are not blogs.</li>
63
+ <li>Email me at <a href="mailto:evil@che.lu">evil@che.lu</a> if you have any questions.</li>
64
+ <li>Happy hacking!</li>
65
+ </ul>
66
+ </div>
67
+ </div>
68
+
69
+ {{ content_for_layout }}
70
+
71
+ </div>
72
+
73
+ </div>
74
+
75
+ <div id="sidebar">
76
+
77
+ <div class="boxy short">
78
+ <h3>boxy short</h3>
79
+
80
+ <p>You can have, boxes with a short, tall or no background shade, just change the class of the containing div.</p>
81
+
82
+ <p>Have boxes with smaller text with the class "minor". See the "Recent" boxy below.</p>
83
+
84
+ </div>
85
+
86
+ <div id="search" class="boxy short">
87
+ <h3>Search</h3>
88
+ <form method="get" action="/search">
89
+ <fieldset>
90
+ <input class="text" type="text" id="q" value="" name="q"/>
91
+ </fieldset>
92
+ </form>
93
+ </div>
94
+
95
+ <div class="boxy tall minor">
96
+ <h3>Recent</h3>
97
+
98
+ <dl>
99
+ <dt>Articles <a class="feed" href="{{ global_feed }}"><span>feed</span></a></dt>
100
+ <dd>
101
+ <ul>
102
+ {% for article in site.latest_articles %}
103
+ <li>{{ article | link_to_article }} <em>({{ article.published_at | format_date: 'stub', true }})</em></li>
104
+ {% endfor %}
105
+ </ul>
106
+ </dd>
107
+
108
+ <dt>Comments <a class="feed" href="{{ global_comments_feed }}"><span>feed</span></a></dt>
109
+ <dd>
110
+ <ul>
111
+ {% for comment in site.latest_comments %}
112
+ <li>{{ comment.author_link }} on <a href="{{ comment.url }}#comment-{{ comment.id }}">{{ comment.title }}</a></li>
113
+ {% endfor %}
114
+ </ul>
115
+ </dd>
116
+ </dl>
117
+ </div>
118
+
119
+ <div class="boxy short">
120
+ <h3>Archives</h3>
121
+ <p>This would be much nicer with jamis' month_drop thingy.</p>
122
+ {{ '' | section | months | assign_to: 'home_section' }}
123
+ <ul>
124
+ {% for month in home_section.months %}
125
+ {{ home_section | monthly_articles: month | size | assign_to: 'articles_count' }}
126
+ {% if articles_count > 0 %}
127
+ <li>{{ home_section | link_to_month: month }} ({{ articles_count }})</li>
128
+ {% endif %}
129
+ {% endfor %}
130
+ </ul>
131
+ </div>
132
+
133
+ {% if site.blog_sections.size > 1 %}
134
+ <div class="boxy short">
135
+ <h3>Categories</h3>
136
+ <p>Lists only blog type categories with at least one article.</p>
137
+ <p>This list uses an ul. You could use a dl with only dd's in it for the same effect. Wouldn't be semantic tho.</p>
138
+ <ul class="sections">
139
+ {% for section in site.blog_sections %}
140
+ {% if section.articles_count > 0 %}
141
+ {% unless section.is_home %}
142
+ <li>{{ section | link_to_section }} ({{ section.articles_count }})</li>
143
+ {% endunless %}
144
+ {% endif %}
145
+ {% endfor %}
146
+ </ul>
147
+ </div>
148
+
149
+ {% endif %}
150
+ {% unless site.tags == empty %}
151
+ <div class="boxy short">
152
+ <p>This would be nicer if we could get the number of articles for each tag.</p>
153
+ <h3>tags: </h3>
154
+ <ul>
155
+ {% for tag in site.tags %}
156
+ <li>{{ tag | link_to_tag }}</li>
157
+ {% endfor %}
158
+ </ul>
159
+ </div>
160
+
161
+ {% endunless %}
162
+ <div class="boxy tall">
163
+ <h3>boxy tall</h3>
164
+ <p>When using a tall box, make sure it's got plenty of content or that it's immediately followed by a short boxy. It might look a bit chopped off otherwise.</p>
165
+ <dl>
166
+ <dt>thing 1</dt>
167
+ <dd><a href="#">value 1</a></dd>
168
+ <dd><a href="#">value 2</a></dd>
169
+ <dd><a href="#">value 3</a></dd>
170
+ <dd><a href="#">value 4</a></dd>
171
+ <dd><a href="#">value 5</a></dd>
172
+ <dd><a href="#">value 6</a></dd>
173
+ <dd><a href="#">value 6</a></dd>
174
+
175
+ <dt>thing 1</dt>
176
+ <dd><a href="#">value 1</a></dd>
177
+ <dd><a href="#">value 2</a></dd>
178
+ <dd><a href="#">value 3</a></dd>
179
+ <dd>value 4</dd>
180
+ <dd>value 5</dd>
181
+ <dd><a href="#">value 6</a></dd>
182
+ <dd><a href="#">value 6</a></dd>
183
+
184
+ </dl>
185
+ </div>
186
+
187
+ </div>
188
+
189
+ </div>
190
+
191
+ <div id="options">
192
+ <h2>Options:</h2>
193
+ <h3>Size</h3>
194
+ <ul id="option_size">
195
+ <li id="option_size_fixed" class="fixed" ><a><span>fixed </span></a></li>
196
+ <li id="option_size_fluid" class="fluid" ><a><span>fluid </span></a></li>
197
+ </ul>
198
+ <h3>Colors</h3>
199
+ <ul id="option_color">
200
+ <li id="option_color_orange" class="orange"><a><span>orange</span></a></li>
201
+ <li id="option_color_blue" class="blue" ><a><span>blue </span></a></li>
202
+ <li id="option_color_green" class="green" ><a><span>green </span></a></li>
203
+ <li id="option_color_pink" class="pink" ><a><span>pink </span></a></li>
204
+ <li id="option_color_cyan" class="cyan" ><a><span>cyan </span></a></li>
205
+ <li id="option_color_red" class="red" ><a><span>red </span></a></li>
206
+ <li id="option_color_violet" class="violet"><a><span>violet</span></a></li>
207
+ </ul>
208
+ </div>
209
+
210
+ <div id="footer">
211
+ <p>Copyright &copy; 2006, Your Name. Valid <a href="http://validator.w3.org/check/referer">XHTML</a> and <a href="http://jigsaw.w3.org/css-validator/check/referer">CSS</a>.</p>
212
+ <p>Using <a href="http://evil.che.lu/projects/skittlish">skittlish</a> on <a href="http://publishwithimpunity.com/">mephisto</a>.</p>
213
+ </div>
214
+
215
+ </div>
216
+
217
+ </body>
218
+
219
+ </html>
@@ -0,0 +1,14 @@
1
+ --- !ruby/object:Hash
2
+ Spoon-Knife: !ruby/object:Hash
3
+ remote: master/braid/Spoon-Knife
4
+ revision: 18
5
+ squashed: true
6
+ type: svn
7
+ url: https://github.com/octocat/Spoon-Knife.git/trunk
8
+ skit1: !ruby/object:Hash
9
+ branch: master
10
+ remote: master/braid/skit1
11
+ revision: 6d3aeac08f9f4f9689d367fc771f5f1c90496176
12
+ squashed: false
13
+ type: git
14
+ url: file:///path/to/braid/spec/fixtures/skit1/.git
@@ -0,0 +1,9 @@
1
+ ### Well hello there!
2
+
3
+ This repository is meant to provide an example for *forking* a repository on GitHub.
4
+
5
+ Creating a *fork* is producing a personal copy of someone else's project. Forks act as a sort of bridge between the original repository and your personal copy. You can submit *Pull Requests* to help make other people's projects better by offering your changes up to the original project. Forking is at the core of social coding at GitHub.
6
+
7
+ After forking this repository, you can make some changes to the project, and submit [a Pull Request](https://github.com/octocat/Spoon-Knife/pulls) as practice.
8
+
9
+ For some more information on how to fork a repository, [check out our guide, "Forking Projects""](http://guides.github.com/overviews/forking/). Thanks! :sparkling_heart:
@@ -0,0 +1,20 @@
1
+ <!DOCTYPE html>
2
+
3
+ <html>
4
+ <head>
5
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
6
+ <title>Spoon-Knife</title>
7
+ <LINK href="styles.css" rel="stylesheet" type="text/css">
8
+ </head>
9
+
10
+ <body>
11
+
12
+ <img src="forkit.gif" id="octocat" alt="" />
13
+
14
+ <!-- Feel free to change this text here -->
15
+ <p>
16
+ Fork me? Fork you, @octocat!
17
+ </p>
18
+
19
+ </body>
20
+ </html>
@@ -0,0 +1,17 @@
1
+ * {
2
+ margin:0px;
3
+ padding:0px;
4
+ }
5
+
6
+ #octocat {
7
+ display: block;
8
+ width:384px;
9
+ margin: 50px auto;
10
+ }
11
+
12
+ p {
13
+ display: block;
14
+ width: 400px;
15
+ margin: 50px auto;
16
+ font: 30px Monaco,"Courier New","DejaVu Sans Mono","Bitstream Vera Sans Mono",monospace;
17
+ }