add the ability to revert whole commits that touch multiple files
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
* Major Enhancements
|
* Major Enhancements
|
||||||
* Add Page sidebars, similar to Page footers.
|
* Add Page sidebars, similar to Page footers.
|
||||||
|
* Add the ability to revert commits to the wiki.
|
||||||
* Minor Enhancements
|
* Minor Enhancements
|
||||||
* Add `:sanitization` and `:history_sanitization` options for customizing
|
* Add `:sanitization` and `:history_sanitization` options for customizing
|
||||||
how `Sanitize.clean` modifies formatted wiki content.
|
how `Sanitize.clean` modifies formatted wiki content.
|
||||||
|
|||||||
+35
-24
@@ -41,6 +41,40 @@ module Gollum
|
|||||||
filename =~ /^_/ ? false : match
|
filename =~ /^_/ ? false : match
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Public: The format of a given filename.
|
||||||
|
#
|
||||||
|
# filename - The String filename.
|
||||||
|
#
|
||||||
|
# Returns the Symbol format of the page. One of:
|
||||||
|
# [ :markdown | :textile | :rdoc | :org | :rest | :asciidoc | :pod |
|
||||||
|
# :roff ]
|
||||||
|
def self.format_for(filename)
|
||||||
|
case filename.to_s
|
||||||
|
when /\.(md|mkdn?|mdown|markdown)$/i
|
||||||
|
:markdown
|
||||||
|
when /\.(textile)$/i
|
||||||
|
:textile
|
||||||
|
when /\.(rdoc)$/i
|
||||||
|
:rdoc
|
||||||
|
when /\.(org)$/i
|
||||||
|
:org
|
||||||
|
when /\.(creole)$/i
|
||||||
|
:creole
|
||||||
|
when /\.(re?st(\.txt)?)$/i
|
||||||
|
:rest
|
||||||
|
when /\.(asciidoc)$/i
|
||||||
|
:asciidoc
|
||||||
|
when /\.(pod)$/i
|
||||||
|
:pod
|
||||||
|
when /\.(\d)$/i
|
||||||
|
:roff
|
||||||
|
when /\.(media)?wiki$/i
|
||||||
|
:mediawiki
|
||||||
|
else
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# Reusable filter to turn a filename (without path) into a canonical name.
|
# Reusable filter to turn a filename (without path) into a canonical name.
|
||||||
# Strips extension, converts spaces to dashes.
|
# Strips extension, converts spaces to dashes.
|
||||||
#
|
#
|
||||||
@@ -143,30 +177,7 @@ module Gollum
|
|||||||
# [ :markdown | :textile | :rdoc | :org | :rest | :asciidoc | :pod |
|
# [ :markdown | :textile | :rdoc | :org | :rest | :asciidoc | :pod |
|
||||||
# :roff ]
|
# :roff ]
|
||||||
def format
|
def format
|
||||||
case @blob.name
|
self.class.format_for(@blob.name)
|
||||||
when /\.(md|mkdn?|mdown|markdown)$/i
|
|
||||||
:markdown
|
|
||||||
when /\.(textile)$/i
|
|
||||||
:textile
|
|
||||||
when /\.(rdoc)$/i
|
|
||||||
:rdoc
|
|
||||||
when /\.(org)$/i
|
|
||||||
:org
|
|
||||||
when /\.(creole)$/i
|
|
||||||
:creole
|
|
||||||
when /\.(re?st(\.txt)?)$/i
|
|
||||||
:rest
|
|
||||||
when /\.(asciidoc)$/i
|
|
||||||
:asciidoc
|
|
||||||
when /\.(pod)$/i
|
|
||||||
:pod
|
|
||||||
when /\.(\d)$/i
|
|
||||||
:roff
|
|
||||||
when /\.(media)?wiki$/i
|
|
||||||
:mediawiki
|
|
||||||
else
|
|
||||||
nil
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Public: The current version of the page.
|
# Public: The current version of the page.
|
||||||
|
|||||||
+44
-5
@@ -257,7 +257,7 @@ module Gollum
|
|||||||
sha1
|
sha1
|
||||||
end
|
end
|
||||||
|
|
||||||
# Public: Reverts a reverse diff for a given page. If only 1 SHA is given,
|
# Public: Applies a reverse diff for a given page. If only 1 SHA is given,
|
||||||
# the reverse diff will be taken from its parent (^SHA...SHA). If two SHAs
|
# the reverse diff will be taken from its parent (^SHA...SHA). If two SHAs
|
||||||
# are given, the reverse diff is taken from SHA1...SHA2.
|
# are given, the reverse diff is taken from SHA1...SHA2.
|
||||||
#
|
#
|
||||||
@@ -286,14 +286,53 @@ module Gollum
|
|||||||
|
|
||||||
index = nil
|
index = nil
|
||||||
sha1 = commit_index(commit) { |i| index = i }
|
sha1 = commit_index(commit) { |i| index = i }
|
||||||
dir = ::File.dirname(page.path)
|
|
||||||
dir = '' if dir == '.'
|
|
||||||
|
|
||||||
@access.refresh
|
@access.refresh
|
||||||
update_working_dir(index, dir, page.name, page.format)
|
|
||||||
|
files = []
|
||||||
|
if page
|
||||||
|
files << [page.path, page.name, page.format]
|
||||||
|
else
|
||||||
|
# Grit::Diff can't parse reverse diffs.... yet
|
||||||
|
lines = patch.split("\n")
|
||||||
|
while line = lines.shift
|
||||||
|
if line =~ %r{^diff --git b/.+? a/(.+)$}
|
||||||
|
path = $1
|
||||||
|
ext = ::File.extname(path)
|
||||||
|
name = ::File.basename(path, ext)
|
||||||
|
if format = ::Gollum::Page.format_for(ext)
|
||||||
|
files << [path, name, format]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
files.each do |(path, name, format)|
|
||||||
|
dir = ::File.dirname(path)
|
||||||
|
dir = '' if dir == '.'
|
||||||
|
update_working_dir(index, dir, name, format)
|
||||||
|
end
|
||||||
|
|
||||||
sha1
|
sha1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Public: Applies a reverse diff to the repo. If only 1 SHA is given,
|
||||||
|
# the reverse diff will be taken from its parent (^SHA...SHA). If two SHAs
|
||||||
|
# are given, the reverse diff is taken from SHA1...SHA2.
|
||||||
|
#
|
||||||
|
# sha1 - String SHA1 of the earlier parent if two SHAs are given,
|
||||||
|
# or the child.
|
||||||
|
# sha2 - Optional String SHA1 of the child.
|
||||||
|
# commit - The commit Hash details:
|
||||||
|
# :message - The String commit message.
|
||||||
|
# :name - The String author full name.
|
||||||
|
# :email - The String email address.
|
||||||
|
#
|
||||||
|
# Returns a String SHA1 of the new commit, or nil if the reverse diff does
|
||||||
|
# not apply.
|
||||||
|
def revert_commit(sha1, sha2 = nil, commit = {})
|
||||||
|
revert_page(nil, sha1, sha2, commit)
|
||||||
|
end
|
||||||
|
|
||||||
# Public: Lists all pages for this wiki.
|
# Public: Lists all pages for this wiki.
|
||||||
#
|
#
|
||||||
# treeish - The String commit ID or ref to find (default: master)
|
# treeish - The String commit ID or ref to find (default: master)
|
||||||
|
|||||||
@@ -12,19 +12,30 @@ context "Page Reverting" do
|
|||||||
end
|
end
|
||||||
|
|
||||||
test "reverts single commit" do
|
test "reverts single commit" do
|
||||||
|
page1 = @wiki.page("B")
|
||||||
|
sha = @wiki.revert_commit('7c45b5f16ff3bae2a0063191ef832701214d4df5')
|
||||||
|
page2 = @wiki.page("B")
|
||||||
|
assert_equal sha, page2.version.sha
|
||||||
|
assert_equal "INITIAL", body=page2.raw_data.strip
|
||||||
|
assert_equal body, File.read(File.join(@path, "B.md")).strip
|
||||||
|
end
|
||||||
|
|
||||||
|
test "reverts single commit for a page" do
|
||||||
page1 = @wiki.page('B')
|
page1 = @wiki.page('B')
|
||||||
sha = @wiki.revert_page(page1, '7c45b5f16ff3bae2a0063191ef832701214d4df5')
|
sha = @wiki.revert_page(page1, '7c45b5f16ff3bae2a0063191ef832701214d4df5')
|
||||||
page2 = @wiki.page('B')
|
page2 = @wiki.page('B')
|
||||||
assert_equal sha, page2.version.sha
|
assert_equal sha, page2.version.sha
|
||||||
assert_equal "INITIAL", page2.raw_data.strip
|
assert_equal "INITIAL", body=page2.raw_data.strip
|
||||||
|
assert_equal body, File.read(File.join(@path, "B.md")).strip
|
||||||
end
|
end
|
||||||
|
|
||||||
test "reverts multiple commits" do
|
test "reverts multiple commits for a page" do
|
||||||
page1 = @wiki.page('A')
|
page1 = @wiki.page('A')
|
||||||
sha = @wiki.revert_page(page1, '302a5491a9a5ba12c7652ac831a44961afa312d2^', 'b26b791cb7917c4f37dd9cb4d1e0efb24ac4d26f')
|
sha = @wiki.revert_page(page1, '302a5491a9a5ba12c7652ac831a44961afa312d2^', 'b26b791cb7917c4f37dd9cb4d1e0efb24ac4d26f')
|
||||||
page2 = @wiki.page('A')
|
page2 = @wiki.page('A')
|
||||||
assert_equal sha, page2.version.sha
|
assert_equal sha, page2.version.sha
|
||||||
assert_equal "INITIAL", page2.raw_data.strip
|
assert_equal "INITIAL", body=page2.raw_data.strip
|
||||||
|
assert_equal body, File.read(File.join(@path, "A.md")).strip
|
||||||
end
|
end
|
||||||
|
|
||||||
test "cannot revert conflicting commit" do
|
test "cannot revert conflicting commit" do
|
||||||
|
|||||||
Reference in New Issue
Block a user