amp 0.5.2 → 0.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +12 -0
- data/.hgignore +3 -0
- data/AUTHORS +1 -1
- data/Manifest.txt +99 -38
- data/README.md +3 -3
- data/Rakefile +53 -18
- data/SCHEDULE.markdown +5 -1
- data/TODO.markdown +120 -149
- data/ampfile.rb +3 -1
- data/bin/amp +4 -1
- data/ext/amp/bz2/extconf.rb +1 -1
- data/ext/amp/mercurial_patch/extconf.rb +1 -1
- data/ext/amp/mercurial_patch/mpatch.c +4 -3
- data/ext/amp/priority_queue/extconf.rb +1 -1
- data/ext/amp/support/extconf.rb +1 -1
- data/ext/amp/support/support.c +1 -1
- data/lib/amp.rb +125 -67
- data/lib/amp/commands/command.rb +12 -10
- data/lib/amp/commands/command_support.rb +8 -1
- data/lib/amp/commands/commands/help.rb +2 -20
- data/lib/amp/commands/commands/init.rb +14 -2
- data/lib/amp/commands/commands/templates.rb +6 -4
- data/lib/amp/commands/commands/version.rb +15 -1
- data/lib/amp/commands/commands/workflow.rb +3 -3
- data/lib/amp/commands/commands/workflows/git/add.rb +3 -3
- data/lib/amp/commands/commands/workflows/git/copy.rb +1 -1
- data/lib/amp/commands/commands/workflows/git/rm.rb +4 -2
- data/lib/amp/commands/commands/workflows/hg/add.rb +1 -1
- data/lib/amp/commands/commands/workflows/hg/addremove.rb +2 -2
- data/lib/amp/commands/commands/workflows/hg/annotate.rb +8 -2
- data/lib/amp/commands/commands/workflows/hg/bisect.rb +253 -0
- data/lib/amp/commands/commands/workflows/hg/branch.rb +1 -1
- data/lib/amp/commands/commands/workflows/hg/branches.rb +3 -3
- data/lib/amp/commands/commands/workflows/hg/bundle.rb +3 -3
- data/lib/amp/commands/commands/workflows/hg/clone.rb +4 -5
- data/lib/amp/commands/commands/workflows/hg/commit.rb +37 -1
- data/lib/amp/commands/commands/workflows/hg/copy.rb +2 -1
- data/lib/amp/commands/commands/workflows/hg/debug/index.rb +1 -1
- data/lib/amp/commands/commands/workflows/hg/diff.rb +3 -8
- data/lib/amp/commands/commands/workflows/hg/forget.rb +5 -4
- data/lib/amp/commands/commands/workflows/hg/identify.rb +6 -6
- data/lib/amp/commands/commands/workflows/hg/import.rb +1 -1
- data/lib/amp/commands/commands/workflows/hg/incoming.rb +2 -2
- data/lib/amp/commands/commands/workflows/hg/log.rb +5 -4
- data/lib/amp/commands/commands/workflows/hg/merge.rb +1 -1
- data/lib/amp/commands/commands/workflows/hg/move.rb +5 -3
- data/lib/amp/commands/commands/workflows/hg/outgoing.rb +1 -1
- data/lib/amp/commands/commands/workflows/hg/push.rb +6 -7
- data/lib/amp/commands/commands/workflows/hg/remove.rb +2 -2
- data/lib/amp/commands/commands/workflows/hg/resolve.rb +6 -23
- data/lib/amp/commands/commands/workflows/hg/root.rb +1 -2
- data/lib/amp/commands/commands/workflows/hg/status.rb +21 -12
- data/lib/amp/commands/commands/workflows/hg/tag.rb +2 -2
- data/lib/amp/commands/commands/workflows/hg/untrack.rb +12 -0
- data/lib/amp/commands/commands/workflows/hg/verify.rb +13 -3
- data/lib/amp/commands/commands/workflows/hg/what_changed.rb +18 -0
- data/lib/amp/commands/dispatch.rb +12 -13
- data/lib/amp/dependencies/amp_support.rb +1 -1
- data/lib/amp/dependencies/amp_support/ruby_amp_support.rb +1 -0
- data/lib/amp/dependencies/maruku.rb +136 -0
- data/lib/amp/dependencies/maruku/attributes.rb +227 -0
- data/lib/amp/dependencies/maruku/defaults.rb +71 -0
- data/lib/amp/dependencies/maruku/errors_management.rb +92 -0
- data/lib/amp/dependencies/maruku/helpers.rb +260 -0
- data/lib/amp/dependencies/maruku/input/charsource.rb +326 -0
- data/lib/amp/dependencies/maruku/input/extensions.rb +69 -0
- data/lib/amp/dependencies/maruku/input/html_helper.rb +189 -0
- data/lib/amp/dependencies/maruku/input/linesource.rb +111 -0
- data/lib/amp/dependencies/maruku/input/parse_block.rb +615 -0
- data/lib/amp/dependencies/maruku/input/parse_doc.rb +234 -0
- data/lib/amp/dependencies/maruku/input/parse_span_better.rb +746 -0
- data/lib/amp/dependencies/maruku/input/rubypants.rb +225 -0
- data/lib/amp/dependencies/maruku/input/type_detection.rb +147 -0
- data/lib/amp/dependencies/maruku/input_textile2/t2_parser.rb +163 -0
- data/lib/amp/dependencies/maruku/maruku.rb +33 -0
- data/lib/amp/dependencies/maruku/output/to_ansi.rb +223 -0
- data/lib/amp/dependencies/maruku/output/to_html.rb +991 -0
- data/lib/amp/dependencies/maruku/output/to_markdown.rb +164 -0
- data/lib/amp/dependencies/maruku/output/to_s.rb +56 -0
- data/lib/amp/dependencies/maruku/string_utils.rb +191 -0
- data/lib/amp/dependencies/maruku/structures.rb +167 -0
- data/lib/amp/dependencies/maruku/structures_inspect.rb +87 -0
- data/lib/amp/dependencies/maruku/structures_iterators.rb +61 -0
- data/lib/amp/dependencies/maruku/textile2.rb +1 -0
- data/lib/amp/dependencies/maruku/toc.rb +199 -0
- data/lib/amp/dependencies/maruku/usage/example1.rb +33 -0
- data/lib/amp/dependencies/maruku/version.rb +40 -0
- data/lib/amp/dependencies/priority_queue.rb +2 -1
- data/lib/amp/dependencies/python_config.rb +2 -1
- data/lib/amp/graphs/ancestor.rb +2 -1
- data/lib/amp/graphs/copies.rb +236 -233
- data/lib/amp/help/entries/__default__.erb +31 -0
- data/lib/amp/help/entries/commands.erb +6 -0
- data/lib/amp/help/entries/mdtest.md +35 -0
- data/lib/amp/help/entries/silly +3 -0
- data/lib/amp/help/help.rb +288 -0
- data/lib/amp/profiling_hacks.rb +5 -3
- data/lib/amp/repository/abstract/abstract_changeset.rb +97 -0
- data/lib/amp/repository/abstract/abstract_local_repo.rb +181 -0
- data/lib/amp/repository/abstract/abstract_staging_area.rb +180 -0
- data/lib/amp/repository/abstract/abstract_versioned_file.rb +100 -0
- data/lib/amp/repository/abstract/common_methods/changeset.rb +75 -0
- data/lib/amp/repository/abstract/common_methods/local_repo.rb +277 -0
- data/lib/amp/repository/abstract/common_methods/staging_area.rb +233 -0
- data/lib/amp/repository/abstract/common_methods/versioned_file.rb +71 -0
- data/lib/amp/repository/generic_repo_picker.rb +78 -0
- data/lib/amp/repository/git/repo_format/changeset.rb +336 -0
- data/lib/amp/repository/git/repo_format/staging_area.rb +192 -0
- data/lib/amp/repository/git/repo_format/versioned_file.rb +119 -0
- data/lib/amp/repository/git/repositories/local_repository.rb +164 -0
- data/lib/amp/repository/git/repository.rb +41 -0
- data/lib/amp/repository/mercurial/encoding/mercurial_diff.rb +382 -0
- data/lib/amp/repository/mercurial/encoding/mercurial_patch.rb +1 -0
- data/lib/amp/repository/mercurial/encoding/patch.rb +294 -0
- data/lib/amp/repository/mercurial/encoding/pure_ruby/ruby_mercurial_patch.rb +124 -0
- data/lib/amp/repository/mercurial/merging/merge_ui.rb +327 -0
- data/lib/amp/repository/mercurial/merging/simple_merge.rb +452 -0
- data/lib/amp/repository/mercurial/repo_format/branch_manager.rb +266 -0
- data/lib/amp/repository/mercurial/repo_format/changeset.rb +768 -0
- data/lib/amp/repository/mercurial/repo_format/dir_state.rb +716 -0
- data/lib/amp/repository/mercurial/repo_format/journal.rb +218 -0
- data/lib/amp/repository/mercurial/repo_format/lock.rb +210 -0
- data/lib/amp/repository/mercurial/repo_format/merge_state.rb +228 -0
- data/lib/amp/repository/mercurial/repo_format/staging_area.rb +367 -0
- data/lib/amp/repository/mercurial/repo_format/store.rb +487 -0
- data/lib/amp/repository/mercurial/repo_format/tag_manager.rb +322 -0
- data/lib/amp/repository/mercurial/repo_format/updatable.rb +543 -0
- data/lib/amp/repository/mercurial/repo_format/updater.rb +848 -0
- data/lib/amp/repository/mercurial/repo_format/verification.rb +433 -0
- data/lib/amp/repository/mercurial/repositories/bundle_repository.rb +216 -0
- data/lib/amp/repository/mercurial/repositories/http_repository.rb +386 -0
- data/lib/amp/repository/mercurial/repositories/local_repository.rb +2034 -0
- data/lib/amp/repository/mercurial/repository.rb +119 -0
- data/lib/amp/repository/mercurial/revlogs/bundle_revlogs.rb +249 -0
- data/lib/amp/repository/mercurial/revlogs/changegroup.rb +217 -0
- data/lib/amp/repository/mercurial/revlogs/changelog.rb +339 -0
- data/lib/amp/repository/mercurial/revlogs/file_log.rb +152 -0
- data/lib/amp/repository/mercurial/revlogs/index.rb +500 -0
- data/lib/amp/repository/mercurial/revlogs/manifest.rb +201 -0
- data/lib/amp/repository/mercurial/revlogs/node.rb +20 -0
- data/lib/amp/repository/mercurial/revlogs/revlog.rb +1026 -0
- data/lib/amp/repository/mercurial/revlogs/revlog_support.rb +129 -0
- data/lib/amp/repository/mercurial/revlogs/versioned_file.rb +597 -0
- data/lib/amp/repository/repository.rb +11 -88
- data/lib/amp/server/extension/amp_extension.rb +3 -3
- data/lib/amp/server/fancy_http_server.rb +1 -1
- data/lib/amp/server/fancy_views/_browser.haml +1 -1
- data/lib/amp/server/fancy_views/_diff_file.haml +1 -8
- data/lib/amp/server/fancy_views/changeset.haml +2 -2
- data/lib/amp/server/fancy_views/file.haml +1 -1
- data/lib/amp/server/fancy_views/file_diff.haml +1 -1
- data/lib/amp/support/amp_ui.rb +13 -29
- data/lib/amp/support/generator.rb +1 -1
- data/lib/amp/support/loaders.rb +1 -2
- data/lib/amp/support/logger.rb +10 -16
- data/lib/amp/support/match.rb +18 -4
- data/lib/amp/support/mercurial/ignore.rb +151 -0
- data/lib/amp/support/openers.rb +8 -3
- data/lib/amp/support/support.rb +91 -46
- data/lib/amp/templates/{blank.commit.erb → mercurial/blank.commit.erb} +0 -0
- data/lib/amp/templates/{blank.log.erb → mercurial/blank.log.erb} +0 -0
- data/lib/amp/templates/{default.commit.erb → mercurial/default.commit.erb} +0 -0
- data/lib/amp/templates/{default.log.erb → mercurial/default.log.erb} +0 -0
- data/lib/amp/templates/template.rb +18 -18
- data/man/amp.1 +51 -0
- data/site/src/about/commands.haml +1 -1
- data/site/src/css/amp.css +1 -1
- data/site/src/index.haml +3 -3
- data/tasks/man.rake +39 -0
- data/tasks/stats.rake +1 -10
- data/tasks/yard.rake +1 -50
- data/test/dirstate_tests/test_dir_state.rb +10 -8
- data/test/functional_tests/annotate.out +31 -0
- data/test/functional_tests/test_functional.rb +155 -63
- data/test/localrepo_tests/ampfile.rb +12 -0
- data/test/localrepo_tests/test_local_repo.rb +56 -57
- data/test/manifest_tests/test_manifest.rb +3 -5
- data/test/merge_tests/test_merge.rb +3 -3
- data/test/revlog_tests/test_revlog.rb +14 -6
- data/test/store_tests/test_fncache_store.rb +19 -19
- data/test/test_19_compatibility.rb +46 -0
- data/test/test_base85.rb +2 -2
- data/test/test_bdiff.rb +2 -2
- data/test/test_changegroup.rb +59 -0
- data/test/test_commands.rb +2 -2
- data/test/test_difflib.rb +2 -2
- data/test/test_generator.rb +34 -0
- data/test/test_ignore.rb +203 -0
- data/test/test_journal.rb +18 -13
- data/test/test_match.rb +2 -2
- data/test/test_mdiff.rb +3 -3
- data/test/test_mpatch.rb +3 -3
- data/test/test_multi_io.rb +40 -0
- data/test/test_support.rb +18 -2
- data/test/test_templates.rb +38 -0
- data/test/test_ui.rb +79 -0
- data/test/testutilities.rb +56 -0
- metadata +168 -49
- data/ext/amp/bz2/mkmf.log +0 -38
- data/lib/amp/encoding/mercurial_diff.rb +0 -378
- data/lib/amp/encoding/mercurial_patch.rb +0 -1
- data/lib/amp/encoding/patch.rb +0 -292
- data/lib/amp/encoding/pure_ruby/ruby_mercurial_patch.rb +0 -123
- data/lib/amp/merges/merge_state.rb +0 -164
- data/lib/amp/merges/merge_ui.rb +0 -322
- data/lib/amp/merges/simple_merge.rb +0 -450
- data/lib/amp/repository/branch_manager.rb +0 -234
- data/lib/amp/repository/dir_state.rb +0 -950
- data/lib/amp/repository/journal.rb +0 -203
- data/lib/amp/repository/lock.rb +0 -207
- data/lib/amp/repository/repositories/bundle_repository.rb +0 -214
- data/lib/amp/repository/repositories/http_repository.rb +0 -377
- data/lib/amp/repository/repositories/local_repository.rb +0 -2661
- data/lib/amp/repository/store.rb +0 -485
- data/lib/amp/repository/tag_manager.rb +0 -319
- data/lib/amp/repository/updatable.rb +0 -532
- data/lib/amp/repository/verification.rb +0 -431
- data/lib/amp/repository/versioned_file.rb +0 -475
- data/lib/amp/revlogs/bundle_revlogs.rb +0 -246
- data/lib/amp/revlogs/changegroup.rb +0 -217
- data/lib/amp/revlogs/changelog.rb +0 -338
- data/lib/amp/revlogs/changeset.rb +0 -521
- data/lib/amp/revlogs/file_log.rb +0 -165
- data/lib/amp/revlogs/index.rb +0 -493
- data/lib/amp/revlogs/manifest.rb +0 -195
- data/lib/amp/revlogs/node.rb +0 -18
- data/lib/amp/revlogs/revlog.rb +0 -1045
- data/lib/amp/revlogs/revlog_support.rb +0 -126
- data/lib/amp/support/ignore.rb +0 -144
- data/site/Rakefile +0 -38
- data/test/test_amp.rb +0 -9
- data/test/test_helper.rb +0 -15
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module Amp
|
|
2
|
+
module Repositories
|
|
3
|
+
module Git
|
|
4
|
+
|
|
5
|
+
class GitPicker < GenericRepoPicker
|
|
6
|
+
|
|
7
|
+
def self.pick(config, path='', create=false)
|
|
8
|
+
# hot path so we don't load the HTTP repos!
|
|
9
|
+
unless path[0,4] == "http"
|
|
10
|
+
return LocalRepository.new(find_repo(path), create, config)
|
|
11
|
+
end
|
|
12
|
+
raise "Unknown repository format for Git"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.repo_in_dir?(path)
|
|
16
|
+
return true if path[0, 4] == "http"
|
|
17
|
+
until File.directory? File.join(path, ".git")
|
|
18
|
+
old_path, path = path, File.dirname(path)
|
|
19
|
+
if path == old_path
|
|
20
|
+
return false
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
true
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
################################
|
|
27
|
+
private
|
|
28
|
+
################################
|
|
29
|
+
def self.find_repo(path)
|
|
30
|
+
until File.directory? File.join(path, ".git")
|
|
31
|
+
old_path, path = path, File.dirname(path)
|
|
32
|
+
if path == old_path
|
|
33
|
+
raise "No Repository Found"
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
path
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
module Amp
|
|
2
|
+
module Diffs
|
|
3
|
+
module Mercurial
|
|
4
|
+
|
|
5
|
+
##
|
|
6
|
+
# = MercurialDiff
|
|
7
|
+
# Mercurial has it's own implementation of the unified diff, because windows
|
|
8
|
+
# boxes don't have diff -u. Plus code is faster than the shell.
|
|
9
|
+
# Lame. That's ok, it's pretty easy to do. And we can also add flags and
|
|
10
|
+
# change default settings.
|
|
11
|
+
#
|
|
12
|
+
# Mainly, you're only going to use MercurialDiff.unified_diff(). It's usage
|
|
13
|
+
# is described below.
|
|
14
|
+
module MercurialDiff
|
|
15
|
+
extend self
|
|
16
|
+
##
|
|
17
|
+
# These are the default options you can modify. Grab them, clone them,
|
|
18
|
+
# change them. Notice: You have to *clone* this when you use it, or
|
|
19
|
+
# you will be changing the default options!
|
|
20
|
+
DEFAULT_OPTIONS = {:context => 3, :text => false, :show_func => false,
|
|
21
|
+
:git => false, :no_dates => false, :ignore_ws => false,
|
|
22
|
+
:ignore_ws_amount => false, :ignore_blank_lines => false,
|
|
23
|
+
:pretty => false}
|
|
24
|
+
|
|
25
|
+
##
|
|
26
|
+
# Clear up whitespace in the text if we have any options relating
|
|
27
|
+
# to getting rid of whitespace.
|
|
28
|
+
#
|
|
29
|
+
# @param [String] text the text to modify
|
|
30
|
+
# @param [Hash] options the options to use when deciding how to clean text
|
|
31
|
+
# @option [Boolean] options :ignore_ws (false) do we ignore all whitespace?
|
|
32
|
+
# this has the net effect of removing all whitespace.
|
|
33
|
+
# @option [Boolean] options :ignore_ws_amount (false) when this option is
|
|
34
|
+
# true, we only remove "excessive" whitespace - more than 1 space or tab.
|
|
35
|
+
# we then substitute it all with 1 space.
|
|
36
|
+
# @option [Boolean] options :ignore_blank_lines (false) when this option
|
|
37
|
+
# is true, we remove all extra blank lines.
|
|
38
|
+
def whitespace_clean(text, options=DEFAULT_OPTIONS)
|
|
39
|
+
if options[:ignore_ws]
|
|
40
|
+
text.gsub!(/[ \t]+/, "") #warnings made me use parens
|
|
41
|
+
elsif options[:ignore_ws_amount]
|
|
42
|
+
text.gsub!(/[ \t]+/, ' ')
|
|
43
|
+
text.gsub!(/[ \t]+\n/, "\n")
|
|
44
|
+
end
|
|
45
|
+
text.gsub!(/\n+/, '') if options[:ignore_blank_lines]
|
|
46
|
+
text
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
##
|
|
50
|
+
# Given a line, returns a string that represents "adding that line" in a diff,
|
|
51
|
+
# based on the options.
|
|
52
|
+
#
|
|
53
|
+
# @param [String] input the input line
|
|
54
|
+
# @return [String] the output line, in a format indicating it is "added"
|
|
55
|
+
def add_line(input, options)
|
|
56
|
+
options[:pretty] ? "+#{input.chomp}".green+"\n" : "+#{input}"
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
##
|
|
60
|
+
# Given a line, returns a string that represents "removing that line" in a diff,
|
|
61
|
+
# based on the options.
|
|
62
|
+
#
|
|
63
|
+
# @param [String] input the input line
|
|
64
|
+
# @return [String] the output line, in a format indicating it is "removed"
|
|
65
|
+
def remove_line(input, options)
|
|
66
|
+
options[:pretty] ? "-#{input.chomp}".red+"\n" : "-#{input}"
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
##
|
|
70
|
+
# Creates a header or something? Not sure what this is used for, no code
|
|
71
|
+
# references it. I think it's for git or something. eh.
|
|
72
|
+
def diff_line(revisions, a, b, options=DEFAULT_OPTIONS)
|
|
73
|
+
options = DEFAULT_OPTIONS.merge options
|
|
74
|
+
parts = ['diff']
|
|
75
|
+
|
|
76
|
+
parts << '--git' if options[:git]
|
|
77
|
+
parts << revisions.map {|r| "-r #{r}"}.join(' ') if revisions && !options[:git]
|
|
78
|
+
if options[:git]
|
|
79
|
+
parts << "a/#{a}"
|
|
80
|
+
parts << "b/#{b}"
|
|
81
|
+
else
|
|
82
|
+
parts << a
|
|
83
|
+
end
|
|
84
|
+
parts.join(' ') + "\n"
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
##
|
|
88
|
+
# Creates a date tag appropriate for diffs. Not all diff types use
|
|
89
|
+
# dates though (namely git, apparently), so the options matter.
|
|
90
|
+
#
|
|
91
|
+
# @param [Time] date the time that we want to make a spiffy date line for
|
|
92
|
+
# @param [String] fn1 the filename of the file being stamped. Only
|
|
93
|
+
# used if the addtab option is on.
|
|
94
|
+
# @param [Boolean] addtab (false) whether or not to add a tab in the
|
|
95
|
+
# line or not. Only used if we're in git mode or no-date mode.
|
|
96
|
+
# @param options the options to use while creating the date line.
|
|
97
|
+
# @option [Boolean] options :git (false) are we creating a git diff?
|
|
98
|
+
# this will deactivate dates.
|
|
99
|
+
# @option options [Boolean] :nodates (false) should we never print dates?
|
|
100
|
+
def date_tag(date, fn1, addtab = true, options = DEFAULT_OPTIONS)
|
|
101
|
+
return "\t#{date.to_diff}\n" if !(options[:git]) && !(options[:nodates])
|
|
102
|
+
return "\t\n" if addtab && fn1 =~ / /
|
|
103
|
+
return "\n"
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
##
|
|
107
|
+
# Returns a unified diff based on the 2 blocks of text, their modification
|
|
108
|
+
# times, their filenames, and the options.
|
|
109
|
+
#
|
|
110
|
+
# This is a self-contained replacement for diffs.
|
|
111
|
+
#
|
|
112
|
+
# @param a the original text
|
|
113
|
+
# @param [Time] ad the modification timestamp for the old file
|
|
114
|
+
# @param b the new text
|
|
115
|
+
# @param [Time] bd the modification timestamp for the new file
|
|
116
|
+
# @param fn1 the old filename
|
|
117
|
+
# @param fn2 the new filename
|
|
118
|
+
# @param r not sure what this does
|
|
119
|
+
# @param options the options we will be using. There's a lot of settings,
|
|
120
|
+
# see the descriptions for {whitespace_clean} and {date_tag}.
|
|
121
|
+
def unified_diff(a, ad, b, bd, fn1, fn2, r=nil, options=DEFAULT_OPTIONS)
|
|
122
|
+
return "" if (a.nil? || a.empty?) && (b.nil? || b.empty?)
|
|
123
|
+
options = DEFAULT_OPTIONS.merge(options) # overlay the defaults with the supplied opts
|
|
124
|
+
epoch = Time.at(0)
|
|
125
|
+
if !options[:text] && (!a.nil? && a.binary? || !b.nil? && b.binary?)
|
|
126
|
+
return "" if a.any? && b.any? && a.size == b.size && a == b #DERR
|
|
127
|
+
l = ["Binary file #{fn1} has changed\n"]
|
|
128
|
+
elsif a.nil? || a.empty?
|
|
129
|
+
b = b.split_lines_better
|
|
130
|
+
header = []
|
|
131
|
+
if options[:pretty]
|
|
132
|
+
l1 = a.nil? ? "Added file " : "Changed file "
|
|
133
|
+
l1 += "#{fn2} at #{date_tag(bd,fn1,true,options)}"
|
|
134
|
+
l1 = l1.cyan
|
|
135
|
+
header << l1
|
|
136
|
+
else
|
|
137
|
+
if a.nil?
|
|
138
|
+
header << "--- /dev/null#{date_tag(epoch, fn1, false, options)}"
|
|
139
|
+
else
|
|
140
|
+
header << "--- #{"a/" + fn1}#{date_tag(ad,fn1,true,options)}"
|
|
141
|
+
end
|
|
142
|
+
header << "+++ #{"b/" + fn2}#{date_tag(bd,fn1,true,options)}"
|
|
143
|
+
header << "@@ -0,0 +1,#{b.size} @@\n"
|
|
144
|
+
end
|
|
145
|
+
l = header + (b.map {|line| add_line(line, options)})
|
|
146
|
+
elsif b.nil? || b.empty?
|
|
147
|
+
a = b.split_lines_better
|
|
148
|
+
header = []
|
|
149
|
+
if options[:pretty]
|
|
150
|
+
l1 = b.nil? ? "Removed file " : "Changed file "
|
|
151
|
+
l1 += "#{fn2} at #{date_tag(bd,fn1,true,options)}"
|
|
152
|
+
l1 = l1.cyan
|
|
153
|
+
header << l1
|
|
154
|
+
else
|
|
155
|
+
header << "--- #{"a/" + fn1}#{date_tag(ad,fn1,true,options)}"
|
|
156
|
+
if b.nil?
|
|
157
|
+
header << "+++ /dev/null#{date_tag(epoch, fn1, false, options)}"
|
|
158
|
+
else
|
|
159
|
+
header << "+++ #{"b/" + fn2}#{date_tag(bd,fn1,true,options)}"
|
|
160
|
+
end
|
|
161
|
+
header << "@@ -1,#{a.size} +0,0 @@\n"
|
|
162
|
+
end
|
|
163
|
+
l = header + (a.map {|line| remove_line(line, options)})
|
|
164
|
+
else
|
|
165
|
+
al = a.split_lines_better
|
|
166
|
+
bl = b.split_lines_better
|
|
167
|
+
l = bunidiff(a, b, al, bl, "a/"+fn1, "b/"+fn2, options)
|
|
168
|
+
return "" if l.nil? || l.empty?
|
|
169
|
+
if options[:pretty]
|
|
170
|
+
l.shift
|
|
171
|
+
if fn1 == fn2
|
|
172
|
+
l[0] = "Changed file #{fn1.cyan} at #{date_tag(bd,fn1,true,options).lstrip}"
|
|
173
|
+
else
|
|
174
|
+
l[0] = "Moved file from #{fn1.cyan} to #{fn2.cyan}"
|
|
175
|
+
end
|
|
176
|
+
else
|
|
177
|
+
l[0] = "#{l[0][0 .. -3]}#{date_tag(ad,fn1,true,options)}"
|
|
178
|
+
l[1] = "#{l[1][0 .. -3]}#{date_tag(bd,fn1,true,options)}"
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
l.size.times do |ln|
|
|
183
|
+
if l[ln][-1,1] != "\n"
|
|
184
|
+
l[ln] << "\n\\n"
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
if r
|
|
189
|
+
l.unshift diff_line(r, fn1, fn2, options)
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
l.join
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
##
|
|
196
|
+
# Starts a block ending context for a change - part of the unified diff
|
|
197
|
+
# format.
|
|
198
|
+
def context_end(l, len, options)
|
|
199
|
+
ret = l + options[:context]
|
|
200
|
+
ret = len if ret > len
|
|
201
|
+
ret
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
##
|
|
205
|
+
# Starts a block starting context for a change - part of the unified diff
|
|
206
|
+
# format.
|
|
207
|
+
def context_start(l, options)
|
|
208
|
+
ret = l - options[:context]
|
|
209
|
+
return 0 if ret < 0
|
|
210
|
+
ret
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
##
|
|
214
|
+
# Given a hunk of changes, yield each line we need to write to the diff.
|
|
215
|
+
#
|
|
216
|
+
# @param [Hash] hunk specifies a block of lines that changed between
|
|
217
|
+
# the two files.
|
|
218
|
+
# @param header the header for the block, if we have one.
|
|
219
|
+
# @param l1 the original lines - used for context (unified diff format)
|
|
220
|
+
# @param delta the lines that have changed thus far
|
|
221
|
+
# @param options settings for the unified diff action. unused mostly here.
|
|
222
|
+
def yield_hunk(hunk, header, l1, delta, options)
|
|
223
|
+
header.each {|x| yield x} if header && header.any?
|
|
224
|
+
delta = hunk[:delta]
|
|
225
|
+
astart, a2, bstart, b2 = hunk[:start_a], hunk[:end_a], hunk[:start_b], hunk[:end_b]
|
|
226
|
+
aend = context_end(a2,l1.size,options)
|
|
227
|
+
alen = aend - astart
|
|
228
|
+
blen = b2 - bstart + aend - a2
|
|
229
|
+
|
|
230
|
+
# i seriously don't know what this does.
|
|
231
|
+
func = ""
|
|
232
|
+
if options[:show_func]
|
|
233
|
+
(astart - 1).downto(0) do |x|
|
|
234
|
+
t = l1[x].rstrip
|
|
235
|
+
if t =~ /\w/
|
|
236
|
+
func = ' ' + t[0 .. 39]
|
|
237
|
+
break
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
# yield the header
|
|
243
|
+
if options[:pretty]
|
|
244
|
+
yield "From original lines #{astart + 1}-#{alen+astart+1}".yellow + "\n"
|
|
245
|
+
else
|
|
246
|
+
yield "@@ -%d,%d +%d,%d @@%s\n" % [astart + 1, alen,
|
|
247
|
+
bstart + 1, blen, func]
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
# then yield each line of changes
|
|
251
|
+
delta.each {|x| yield x}
|
|
252
|
+
# then yield some context or something?
|
|
253
|
+
a2.upto(aend-1) {|x| yield ' ' + l1[x] }
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
##
|
|
257
|
+
# Helper method for creating unified diffs.
|
|
258
|
+
#
|
|
259
|
+
# @param [String] t1 original text
|
|
260
|
+
# @param [String] t2 new text
|
|
261
|
+
# @param [String] l1 the original text broke into lines?
|
|
262
|
+
# @param [String] l2 the new etxt broken into lines?
|
|
263
|
+
# @param [String] header1 the original file's header
|
|
264
|
+
# @param [String] header2 the new file's header
|
|
265
|
+
# @param opts options for the method
|
|
266
|
+
def bunidiff(t1,t2, l1, l2, header1, header2, opts=DEFAULT_OPTIONS)
|
|
267
|
+
header = [ "--- #{header1}\t\n", "+++ #{header2}\t\n" ]
|
|
268
|
+
|
|
269
|
+
diff = BinaryDiff.blocks(t1,t2)
|
|
270
|
+
hunk = nil
|
|
271
|
+
return_hunks = []
|
|
272
|
+
saved_delta = []
|
|
273
|
+
delta = []
|
|
274
|
+
diff.size.times do |i|
|
|
275
|
+
s = (i > 0) ? diff[i-1] : {:start_a => 0, :end_a => 0, :start_b => 0, :end_b => 0}
|
|
276
|
+
saved_delta += delta unless delta.empty?
|
|
277
|
+
delta = []
|
|
278
|
+
s1 = diff[i]
|
|
279
|
+
a1 = s[:end_a]
|
|
280
|
+
a2 = s1[:start_a]
|
|
281
|
+
b1 = s[:end_b]
|
|
282
|
+
b2 = s1[:start_b]
|
|
283
|
+
|
|
284
|
+
old = (a2 == 0) ? [] : l1[a1..(a2-1)]
|
|
285
|
+
newb = (b2 == 0) ? [] : l2[b1..(b2-1)] #stands for new "b"
|
|
286
|
+
|
|
287
|
+
next if old.empty? && newb.empty?
|
|
288
|
+
if opts[:ignore_ws] || opts[:ignore_blank_lines] || opts[:ignore_ws_amount]
|
|
289
|
+
next if whitespace_clean(old.join,opts) == whitespace_clean(newb.join,opts)
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
astart = context_start(a1,opts)
|
|
293
|
+
bstart = context_start(b1,opts)
|
|
294
|
+
prev = nil
|
|
295
|
+
if hunk
|
|
296
|
+
if astart < hunk[:end_a] + opts[:context] + 1
|
|
297
|
+
prev = hunk
|
|
298
|
+
astart = hunk[:end_a]
|
|
299
|
+
bstart = hunk[:end_b]
|
|
300
|
+
else
|
|
301
|
+
yield_hunk(hunk, header, l1, delta, opts) {|x| return_hunks << x}
|
|
302
|
+
|
|
303
|
+
header = nil
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
# move this inside previous nested if statements
|
|
307
|
+
if prev
|
|
308
|
+
hunk[:end_a] = a2
|
|
309
|
+
hunk[:end_b] = b2
|
|
310
|
+
delta = hunk[:delta]
|
|
311
|
+
else
|
|
312
|
+
hunk = {:start_a => astart, :end_a => a2, :start_b => bstart, :end_b => b2, :delta => delta}
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
hunk[:delta] += l1[astart..(a1-1)].map {|x| ' ' + x } if a1 > 0
|
|
316
|
+
hunk[:delta] += old.map {|x| remove_line(x, opts) }
|
|
317
|
+
hunk[:delta] += newb.map {|x| add_line(x, opts) }
|
|
318
|
+
|
|
319
|
+
end
|
|
320
|
+
saved_delta += delta
|
|
321
|
+
|
|
322
|
+
yield_hunk(hunk, header, l1, saved_delta, opts) {|x| return_hunks << x} if hunk
|
|
323
|
+
return_hunks
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
##
|
|
327
|
+
# Unpacks a binary-compressed patch.
|
|
328
|
+
#
|
|
329
|
+
# @param [String] binary the packed binary text to unpack
|
|
330
|
+
def patch_text(binary)
|
|
331
|
+
pos = 0
|
|
332
|
+
t = []
|
|
333
|
+
while pos < binary.size
|
|
334
|
+
p1, p2, l = binary[pos..(pos+11)].unpack("NNN")
|
|
335
|
+
pos += 12
|
|
336
|
+
t << binary[pos..(pos + l - 1)]
|
|
337
|
+
pos += l
|
|
338
|
+
end
|
|
339
|
+
t.join
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
##
|
|
343
|
+
# Applies the patch _bin_ to the text _a_.
|
|
344
|
+
#
|
|
345
|
+
# @param [String] a the text to patch
|
|
346
|
+
# @param [String] bin the binary patch to apply
|
|
347
|
+
def patch(a, bin)
|
|
348
|
+
MercurialPatch.apply_patches(a, [bin])
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
##
|
|
352
|
+
# Gets the matching blocks between the two texts.
|
|
353
|
+
#
|
|
354
|
+
# @param [String] a the original text
|
|
355
|
+
# @param [String] b the final text
|
|
356
|
+
# @return [[Hash]] The blocks of changes between the two
|
|
357
|
+
def get_matching_blocks(a, b)
|
|
358
|
+
an = a.split_lines_better
|
|
359
|
+
bn = b.split_lines_better
|
|
360
|
+
|
|
361
|
+
SequenceMatcher.new(an, bn).get_matching_blocks
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
##
|
|
365
|
+
# Returns the obvious header for when we create a new file
|
|
366
|
+
#
|
|
367
|
+
# @param [Fixnum] length the length of the file
|
|
368
|
+
# @return [String] the obvious header
|
|
369
|
+
def trivial_diff_header(length)
|
|
370
|
+
[0, 0, length].pack("NNN")
|
|
371
|
+
end
|
|
372
|
+
|
|
373
|
+
##
|
|
374
|
+
# Returns a text diff between a and b. This returns the packed, binary
|
|
375
|
+
# kind of diff.
|
|
376
|
+
def text_diff a,b
|
|
377
|
+
BinaryDiff.bdiff a,b
|
|
378
|
+
end
|
|
379
|
+
end
|
|
380
|
+
end
|
|
381
|
+
end
|
|
382
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
amp_c_extension 'amp/mercurial_patch/CMercurialPatch', 'pure_ruby/ruby_mercurial_patch'
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
# I have seen few files so poorly organized such as patch.py
|
|
2
|
+
# What. The. Fuck. This is going to take so long to make.
|
|
3
|
+
module Amp
|
|
4
|
+
module Patch
|
|
5
|
+
module Mercurial
|
|
6
|
+
|
|
7
|
+
class PatchError < StandardError; end
|
|
8
|
+
class NoHunkError < PatchError; end
|
|
9
|
+
|
|
10
|
+
class Patch
|
|
11
|
+
|
|
12
|
+
##
|
|
13
|
+
# The filename of the patch
|
|
14
|
+
attr_accessor :file_name
|
|
15
|
+
|
|
16
|
+
##
|
|
17
|
+
# The opener used to open the patch
|
|
18
|
+
attr_accessor :opener
|
|
19
|
+
|
|
20
|
+
##
|
|
21
|
+
# @todo - add comment
|
|
22
|
+
attr_accessor :lines
|
|
23
|
+
|
|
24
|
+
##
|
|
25
|
+
# does the patch exist?
|
|
26
|
+
attr_accessor :exists
|
|
27
|
+
alias_method :exists?, :exists
|
|
28
|
+
|
|
29
|
+
##
|
|
30
|
+
# Is the file in the filesystem
|
|
31
|
+
attr_accessor :missing
|
|
32
|
+
alias_method :missing?, :missing
|
|
33
|
+
|
|
34
|
+
##
|
|
35
|
+
# @todo - add comment
|
|
36
|
+
attr_accessor :hash
|
|
37
|
+
|
|
38
|
+
##
|
|
39
|
+
# Is this dirty and does it need to be resynced with something?
|
|
40
|
+
attr_accessor :dirty
|
|
41
|
+
alias_method :dirty?, :dirty
|
|
42
|
+
|
|
43
|
+
##
|
|
44
|
+
# @todo - add comment
|
|
45
|
+
attr_accessor :offset
|
|
46
|
+
|
|
47
|
+
##
|
|
48
|
+
# has this been printed? (duh)
|
|
49
|
+
attr_accessor :printed
|
|
50
|
+
alias_method :printed?, :printed
|
|
51
|
+
|
|
52
|
+
##
|
|
53
|
+
# @todo - add comment
|
|
54
|
+
attr_accessor :hunks
|
|
55
|
+
|
|
56
|
+
def initialize(file_name, opener, missing=false)
|
|
57
|
+
@file_name = file_name
|
|
58
|
+
@opener = opener
|
|
59
|
+
@lines = []
|
|
60
|
+
@exists = false
|
|
61
|
+
@hash = {}
|
|
62
|
+
@dirty = false
|
|
63
|
+
@offset = 0
|
|
64
|
+
@rejected = []
|
|
65
|
+
@printed = false
|
|
66
|
+
@hunks = 0
|
|
67
|
+
|
|
68
|
+
##
|
|
69
|
+
# If the patch is in the filesystem
|
|
70
|
+
# then we should read it and accurately set its existence
|
|
71
|
+
unless @missing = missing
|
|
72
|
+
begin
|
|
73
|
+
readlines!
|
|
74
|
+
@exists = true
|
|
75
|
+
rescue IOError
|
|
76
|
+
end
|
|
77
|
+
else
|
|
78
|
+
UI::warn "unable to find '#{@file_name}' for patching"
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
##
|
|
83
|
+
# Loads up the patch info from +@file_name+
|
|
84
|
+
# into +@lines+
|
|
85
|
+
def readlines!
|
|
86
|
+
@opener.open @file_name do |f|
|
|
87
|
+
@lines = f.readlines
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
##
|
|
92
|
+
# Mysteriously and safely disappear...
|
|
93
|
+
#
|
|
94
|
+
# @return [Boolean] success marker
|
|
95
|
+
def unlink; File.safe_unlink @file_name; end
|
|
96
|
+
|
|
97
|
+
##
|
|
98
|
+
# Print out the patch to STDOUT, or STDERR if +warn+ is true.
|
|
99
|
+
#
|
|
100
|
+
# @param [Boolean] warn should we be printing to STDERR?
|
|
101
|
+
def print(warn=false)
|
|
102
|
+
return if printed? # no need to print it twice
|
|
103
|
+
|
|
104
|
+
@printed = true if warn
|
|
105
|
+
message = "patching file #{@file_name}"
|
|
106
|
+
warn ? UI::warn message : UI::note message
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
##
|
|
110
|
+
# From the Python: looks through the hash and finds candidate lines. The
|
|
111
|
+
# result is a list of line numbers sorted based on distance from linenum.
|
|
112
|
+
#
|
|
113
|
+
# I wish I knew how to make sense of that sentence.
|
|
114
|
+
#
|
|
115
|
+
# @todo Look into removing an unnecessary `- number`.
|
|
116
|
+
# @param [String] line
|
|
117
|
+
# @param [Integer] number the line number
|
|
118
|
+
# @return [Array] the lines that matchish.
|
|
119
|
+
def find_lines(line, number)
|
|
120
|
+
return [] unless @hash.include? line
|
|
121
|
+
|
|
122
|
+
# really, we're just getting the lines and sorting them
|
|
123
|
+
# is the `- number` even necessary?
|
|
124
|
+
@hash[line].sort {|a, b| (a - number).abs <=> (b - number).abs }
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
##
|
|
128
|
+
# I have no clue what song I am listening to but it is SOOOOO GOOD!!!!!!!!
|
|
129
|
+
# "This time baby, I'll be bullet proof"
|
|
130
|
+
# If I had working internet now, I'd be googling the lyrics.
|
|
131
|
+
#
|
|
132
|
+
# Oh right, the method. I don't know what this does... YET
|
|
133
|
+
#
|
|
134
|
+
# @todo Figure out what this does
|
|
135
|
+
def hash_lines
|
|
136
|
+
@hash = Hash.new {|h, k| h[k] = [] }
|
|
137
|
+
(0 ... @lines.size).each do |x|
|
|
138
|
+
s = @lines[x]
|
|
139
|
+
@hash[s] << x
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
##
|
|
144
|
+
# our rejects are a little different from patch(1). This always
|
|
145
|
+
# creates rejects in the same form as the original patch. A file
|
|
146
|
+
# header is inserted so that you can run the reject through patch again
|
|
147
|
+
# without having to type the filename.
|
|
148
|
+
def write_rejects
|
|
149
|
+
return if @rejects.empty?
|
|
150
|
+
fname = @file_name + '.rej'
|
|
151
|
+
|
|
152
|
+
UI::warn("#{@rejects.size} out of #{@hunks} hunks FAILED --" +
|
|
153
|
+
"saving rejects to file #{fname}")
|
|
154
|
+
|
|
155
|
+
# i have never written code as horrid as this
|
|
156
|
+
# please help me
|
|
157
|
+
lz = []
|
|
158
|
+
base = File.dirname @file_name
|
|
159
|
+
lz << "--- #{base}\n+++ #{base}\n"
|
|
160
|
+
@rejects.each do |r|
|
|
161
|
+
r.hunk.each do |l|
|
|
162
|
+
lz << l
|
|
163
|
+
lz << "\n\n" if l.last.chr != "\n"
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
write fname, lz, true
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
##
|
|
171
|
+
# Write +linez+ to +fname+. We won't be doing any writing if
|
|
172
|
+
# nothing has been changed, but this can be overridden with the
|
|
173
|
+
# force parameter.
|
|
174
|
+
#
|
|
175
|
+
# @param [String] dest the filename to write to
|
|
176
|
+
# @param [Array<String>] linez an array of the lines to write
|
|
177
|
+
# @param [Boolean] force force a write
|
|
178
|
+
def write(dest=@file_name, linez=@lines, force=false)
|
|
179
|
+
return unless dirty? || force
|
|
180
|
+
|
|
181
|
+
@opener.open dest, 'w' do |f|
|
|
182
|
+
f.write linez.join("\n")
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
##
|
|
187
|
+
# A more restrictive version of {write}
|
|
188
|
+
def write_patch
|
|
189
|
+
write @file_name, @lines, true
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
##
|
|
193
|
+
# Closing rites. Write the patch and then write the rejects.
|
|
194
|
+
def close
|
|
195
|
+
write_patch
|
|
196
|
+
write_rejects
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
##
|
|
200
|
+
# Apply the current hunk +hunk+. Also, should we reverse the hunk? Consult +reverse+.
|
|
201
|
+
#
|
|
202
|
+
# @param
|
|
203
|
+
# @param
|
|
204
|
+
def apply(hunk, reverse)
|
|
205
|
+
unless hunk.complete?
|
|
206
|
+
raise PatchError.new("bad hunk #%d %s (%d %d %d %d)" %
|
|
207
|
+
[hunk.number, hunk.desc, hunk.a.size,
|
|
208
|
+
hunk.len_a, hunk.b.size, hunk.len_b])
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
@hunks += 1 # It's clear we're adding a new hunk.
|
|
212
|
+
|
|
213
|
+
# Obey reversal rules.
|
|
214
|
+
hunk.reverse if reverse
|
|
215
|
+
|
|
216
|
+
# Does the file already exist? Better tell someone
|
|
217
|
+
UI::warn "file #{@file_name} already exists" if exists? && hunk.create_file?
|
|
218
|
+
|
|
219
|
+
# Is this a misfit?
|
|
220
|
+
(@rejects << hunk; return -1) if missing? || (exists? && hunk.create_file?)
|
|
221
|
+
|
|
222
|
+
# Deal with GitHunks
|
|
223
|
+
if hunk.is_a? GitHunk
|
|
224
|
+
if hunk.remove_file?
|
|
225
|
+
File.safe_unlink @file_name
|
|
226
|
+
else
|
|
227
|
+
@lines = hunk.new
|
|
228
|
+
@offset += hunk.new.size
|
|
229
|
+
@dirty = true
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
return 0
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
# fast case first, no offsets, no fuzz
|
|
236
|
+
old = hunk.old
|
|
237
|
+
|
|
238
|
+
# patch starts counting at 1 unless we are adding the file
|
|
239
|
+
start = hunk.start_a == 0 ? 0 : h.start_a + @offset - 1
|
|
240
|
+
|
|
241
|
+
orig_start = start
|
|
242
|
+
if DiffHelpers::test_hunk(old, @lines, start) == 0
|
|
243
|
+
if hunk.remove_file?
|
|
244
|
+
File.safe_unlink @file_name
|
|
245
|
+
else
|
|
246
|
+
@lines[start .. (start + hunk.len_a)] = hunk.new
|
|
247
|
+
@offset += hunk.len_b - hunk.len_a
|
|
248
|
+
@dirty = true
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
return 0
|
|
252
|
+
end # end if
|
|
253
|
+
end # end def
|
|
254
|
+
|
|
255
|
+
# Ok, We couldn't match the hunk. Let's look for offsets and fuzz it
|
|
256
|
+
# as well as use proper punctuation for the 'let us' contraction.
|
|
257
|
+
hash_lines
|
|
258
|
+
|
|
259
|
+
# if the hunk tried to put something at the bottom of the file
|
|
260
|
+
# then override the start line and use eof here
|
|
261
|
+
search_start = hunk[-1][0].chr != ' ' ? @lines.size : orig_start
|
|
262
|
+
|
|
263
|
+
0.upto(2) do |fuzz_len|
|
|
264
|
+
[true, false].each do |top_only|
|
|
265
|
+
old = hunk.old fuzz_len, top_only
|
|
266
|
+
# Continue at patch.py:407
|
|
267
|
+
# ...
|
|
268
|
+
# ...
|
|
269
|
+
end
|
|
270
|
+
end # end upto
|
|
271
|
+
|
|
272
|
+
end # end class Patch
|
|
273
|
+
|
|
274
|
+
class PatchMeta
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
class Hunk
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
class GitHunk
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
class BinaryHunk
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
class SymLinkHunk
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
class LineReader
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
end
|
|
293
|
+
end
|
|
294
|
+
end
|