git-whistles 0.10.0 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rspec +3 -0
- data/Gemfile.lock +44 -30
- data/HISTORY +3 -0
- data/LICENSE +2 -1
- data/README.md +1 -1
- data/Rakefile +4 -0
- data/bin/git-explore +26 -18
- data/bin/git-select +11 -2
- data/git-whistles.gemspec +1 -0
- data/lib/git-whistles/version.rb +1 -1
- data/libexec/git-merge-po.sh +107 -18
- data/spec/data/base.po +38 -0
- data/spec/data/local.po +39 -0
- data/spec/data/remote.po +39 -0
- data/spec/git_merge_po_spec.rb +96 -0
- data/spec/spec_helper.rb +91 -0
- metadata +30 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0dfecbaa72332d106bea15de20936889f5727b60
|
4
|
+
data.tar.gz: edb8b72b014ac70f5f30f14c3a9609b021dc3383
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fe3610cc0f37ea562b1bcf9ff0752b28b82c9d2b238c79b35d92f010c1c4a45b42aa24164e293e8f159da8fc6ed12e4c681f6b5db61a323ce3327f2124d03169
|
7
|
+
data.tar.gz: 91f6f0a401f63ff6a555bc5426705bd7348baa9ab721a7624810a7a985d2857c2feaea8e0fef700fc17a329f493c4e8235922a09538df51affb2c318417c6bc9
|
data/.rspec
ADDED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
git-whistles (0.
|
4
|
+
git-whistles (0.12.0)
|
5
5
|
pivotal-tracker (~> 0.5.6)
|
6
6
|
term-ansicolor
|
7
7
|
|
@@ -9,47 +9,60 @@ GEM
|
|
9
9
|
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
11
|
builder (3.2.2)
|
12
|
-
coderay (1.0
|
12
|
+
coderay (1.1.0)
|
13
13
|
crack (0.4.2)
|
14
14
|
safe_yaml (~> 1.0.0)
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
diff-lcs (1.2.5)
|
16
|
+
domain_name (0.5.23)
|
17
|
+
unf (>= 0.0.5, < 1.0.0)
|
18
|
+
http-cookie (1.0.2)
|
19
|
+
domain_name (~> 0.5)
|
19
20
|
method_source (0.8.2)
|
20
|
-
mime-types (
|
21
|
-
mini_portile (0.6.
|
22
|
-
|
23
|
-
|
21
|
+
mime-types (2.4.3)
|
22
|
+
mini_portile (0.6.2)
|
23
|
+
netrc (0.10.3)
|
24
|
+
nokogiri (1.6.6.2)
|
25
|
+
mini_portile (~> 0.6.0)
|
24
26
|
nokogiri-happymapper (0.5.9)
|
25
27
|
nokogiri (~> 1.5)
|
26
|
-
pivotal-tracker (0.5.
|
27
|
-
builder
|
28
|
+
pivotal-tracker (0.5.13)
|
28
29
|
builder
|
29
30
|
crack
|
30
|
-
happymapper (>= 0.3.2)
|
31
|
-
nokogiri (>= 1.4.3)
|
32
31
|
nokogiri (>= 1.5.5)
|
33
32
|
nokogiri-happymapper (>= 0.5.4)
|
34
|
-
rest-client (
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
method_source (~> 0.8)
|
33
|
+
rest-client (>= 1.8.0)
|
34
|
+
pry (0.10.1)
|
35
|
+
coderay (~> 1.1.0)
|
36
|
+
method_source (~> 0.8.1)
|
39
37
|
slop (~> 3.4)
|
40
|
-
pry-nav (0.2.
|
41
|
-
pry (
|
42
|
-
rake (10.
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
38
|
+
pry-nav (0.2.4)
|
39
|
+
pry (>= 0.9.10, < 0.11.0)
|
40
|
+
rake (10.4.2)
|
41
|
+
rest-client (1.8.0)
|
42
|
+
http-cookie (>= 1.0.2, < 2.0)
|
43
|
+
mime-types (>= 1.16, < 3.0)
|
44
|
+
netrc (~> 0.7)
|
45
|
+
rspec (3.2.0)
|
46
|
+
rspec-core (~> 3.2.0)
|
47
|
+
rspec-expectations (~> 3.2.0)
|
48
|
+
rspec-mocks (~> 3.2.0)
|
49
|
+
rspec-core (3.2.3)
|
50
|
+
rspec-support (~> 3.2.0)
|
51
|
+
rspec-expectations (3.2.1)
|
52
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
53
|
+
rspec-support (~> 3.2.0)
|
54
|
+
rspec-mocks (3.2.1)
|
55
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
56
|
+
rspec-support (~> 3.2.0)
|
57
|
+
rspec-support (3.2.2)
|
58
|
+
safe_yaml (1.0.4)
|
59
|
+
slop (3.6.0)
|
50
60
|
term-ansicolor (1.3.0)
|
51
61
|
tins (~> 1.0)
|
52
|
-
tins (1.3.
|
62
|
+
tins (1.3.5)
|
63
|
+
unf (0.1.4)
|
64
|
+
unf_ext
|
65
|
+
unf_ext (0.0.6)
|
53
66
|
|
54
67
|
PLATFORMS
|
55
68
|
ruby
|
@@ -60,3 +73,4 @@ DEPENDENCIES
|
|
60
73
|
pry
|
61
74
|
pry-nav
|
62
75
|
rake
|
76
|
+
rspec
|
data/HISTORY
CHANGED
data/LICENSE
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
Copyright (c) 2012-2013 HouseTrip Ltd
|
2
|
+
parts Copyright (c) 2014-2015 Julien Letessier <julien.letessier@gmail.com>
|
2
3
|
|
3
4
|
MIT License
|
4
5
|
|
@@ -19,4 +20,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
20
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
21
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
22
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
23
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -19,7 +19,7 @@ Use it with:
|
|
19
19
|
| `git chop [branch ...]` | Deletes the local and origin copy of a branch. Useful to close feature branches once a feature is completed. It also accepts multiple branches separated by spaces [[David Silva](https://github.com/Davidslv)] |
|
20
20
|
| `git list-branches [-l] [-r] [-i integration-branch]` | Colourful listing of all local or origin branches, and their distance to an integration branch (`master` by default). |
|
21
21
|
| `git merge-po <ancestor> <left> <right>` | Merge engine for GetText PO files. |
|
22
|
-
| `git select <story-id
|
22
|
+
| `git select <story-id> [-p PREFIX]` | Checkout a local branch with the matching number. If not found, lists remote branches. With -p you can add a prefix to your local branch name. |
|
23
23
|
| `git latest-pushes [-n NR_RESULTS] [-p PATTERN]` | Show latest pushed branches to origin. Defaults to 20 results. Pattern is appended to refs/remotes/origin/ so include the team or project name to filter results. [[PedroCunha](https://github.com/PedroCunha)] |
|
24
24
|
| `git pivotal-branch <story-id>` | Creates a branch name suggestion from the specified Pivotal Tracker story ID. It also comments on the story the branch name created and starts the story [[dncrht](https://github.com/dncrht)] |
|
25
25
|
| `git pivotal-open [story-id]` | Opens the Pivotal Tracker story page for the current branch, from the specified Pivotal Tracker story ID or it is inferred from the branch name if not supplied [[khiet](https://github.com/khiet)] |
|
data/Rakefile
CHANGED
data/bin/git-explore
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# encoding: UTF-8
|
3
3
|
#
|
4
|
-
# git-explore [-r ref] [-p path]
|
4
|
+
# git-explore [-r ref] [-p path] [-l line[-line]]
|
5
5
|
#
|
6
6
|
# Explore the given reference on the remote origin website
|
7
7
|
#
|
@@ -12,28 +12,31 @@ require 'git-whistles/app'
|
|
12
12
|
|
13
13
|
class App < Git::Whistles::App
|
14
14
|
|
15
|
-
GITHUB_URL = 'https://
|
15
|
+
GITHUB_URL = 'https://github.com'
|
16
16
|
|
17
17
|
def main(args)
|
18
18
|
super
|
19
19
|
parse_args!(args)
|
20
20
|
|
21
|
-
|
21
|
+
@origin = run!("git config --get remote.origin.url").strip
|
22
22
|
|
23
|
-
|
23
|
+
unless github?
|
24
|
+
die 'Unknown origin. Only github supported at the moment', usage: true
|
25
|
+
end
|
24
26
|
|
25
27
|
# This has to support both variants
|
26
28
|
# https://github.com/mezis/git-whistles.git
|
27
29
|
# git@github.com:mezis/git-whistles.git
|
28
|
-
|
29
|
-
|
30
|
-
|
30
|
+
unless @origin.match /github\.com[:\/](.+)\.git/
|
31
|
+
die "Error parsing #{@origin} could not find repo"
|
32
|
+
end
|
31
33
|
|
32
34
|
repo = $1
|
33
|
-
|
34
|
-
|
35
|
+
path = options.path ? "/#{ options.path.strip }" : nil
|
36
|
+
reference = path ? "/blob/#{ options.ref.strip }" : "/tree/#{ options.ref.strip }"
|
37
|
+
lines = path && options.lines ? "##{options.lines.split('-').map{ |line| "L#{line}" }.join('-')}" : ''
|
35
38
|
|
36
|
-
url = "#{GITHUB_URL}/#{repo}
|
39
|
+
url = "#{GITHUB_URL}/#{repo}#{reference}#{path}#{lines}"
|
37
40
|
|
38
41
|
puts "opening #{ url }..."
|
39
42
|
run! "open #{ url }"
|
@@ -41,24 +44,28 @@ class App < Git::Whistles::App
|
|
41
44
|
|
42
45
|
def defaults
|
43
46
|
{
|
44
|
-
:
|
45
|
-
:
|
47
|
+
ref: run!('git rev-parse --abbrev-ref HEAD'),
|
48
|
+
file: nil
|
46
49
|
}
|
47
50
|
end
|
48
51
|
|
49
52
|
def option_parser
|
50
53
|
@option_parser ||= OptionParser.new do |op|
|
51
|
-
op.banner = "Usage: git explore [-
|
54
|
+
op.banner = "Usage: git explore [-r ref] [-p path] [-l line[-line]]"
|
52
55
|
|
53
|
-
op.on(
|
56
|
+
op.on('-r', '--ref REFERENCE', 'Reference to explore. Defaults to current branch') do |ref|
|
54
57
|
options.ref = ref
|
55
58
|
end
|
56
59
|
|
57
|
-
op.on(
|
60
|
+
op.on('-p', '--path PATH', 'Path to explore. Defaults to /') do |path|
|
58
61
|
options.path = path
|
59
62
|
end
|
60
63
|
|
61
|
-
op.
|
64
|
+
op.on('-l', '--line LINE', 'Line(s) to highlight. Examples: "2", "10-15". Defaults to nil') do |lines|
|
65
|
+
options.lines = lines
|
66
|
+
end
|
67
|
+
|
68
|
+
op.on_tail('-h', '--help', 'Show this message') do
|
62
69
|
puts op
|
63
70
|
exit
|
64
71
|
end
|
@@ -66,8 +73,9 @@ class App < Git::Whistles::App
|
|
66
73
|
end
|
67
74
|
|
68
75
|
private
|
69
|
-
|
70
|
-
|
76
|
+
|
77
|
+
def github?
|
78
|
+
@origin.match %r{github.com}
|
71
79
|
end
|
72
80
|
|
73
81
|
end
|
data/bin/git-select
CHANGED
@@ -22,7 +22,7 @@ class App < Git::Whistles::App
|
|
22
22
|
parse_args!(args)
|
23
23
|
|
24
24
|
die "Missing story id", :usage => true if args.count == 0
|
25
|
-
die "Too many arguments", :usage => true if args.count >
|
25
|
+
die "Too many arguments", :usage => true if args.count > 2
|
26
26
|
|
27
27
|
story_id = args.first
|
28
28
|
|
@@ -61,13 +61,17 @@ class App < Git::Whistles::App
|
|
61
61
|
when 0
|
62
62
|
puts yellow 'failed lookup on remote branches'
|
63
63
|
when 1
|
64
|
-
if options.
|
64
|
+
if options.prefix
|
65
|
+
`git checkout --track -b #{options.prefix_value}/#{branch_name(found.first)} origin/#{branch_name(found.first)}`
|
66
|
+
exit 0
|
67
|
+
elsif options.remote_checkout
|
65
68
|
`git checkout #{branch_name(found.first)}`
|
66
69
|
exit 0
|
67
70
|
else
|
68
71
|
puts "found #{green(branch_name(found.first))} on remote"
|
69
72
|
puts "by default remote branches are not checked out"
|
70
73
|
puts "if you want to checkout do: #{green "git select -r #{story_id}"}"
|
74
|
+
puts "if you want to checkout with a prefix: #{green "git select -o #{story_id}"}"
|
71
75
|
exit 1
|
72
76
|
end
|
73
77
|
else
|
@@ -94,6 +98,11 @@ class App < Git::Whistles::App
|
|
94
98
|
options.remote_checkout = true
|
95
99
|
end
|
96
100
|
|
101
|
+
op.on("-p", "--prefix PREFIX", "Checkout a remote branch and adds a prefix to the branch name") do |v|
|
102
|
+
options.prefix = true
|
103
|
+
options.prefix_value = v
|
104
|
+
end
|
105
|
+
|
97
106
|
op.on_tail("-h", "--help", "Show this message") do
|
98
107
|
puts op
|
99
108
|
exit
|
data/git-whistles.gemspec
CHANGED
@@ -19,6 +19,7 @@ Gem::Specification.new do |gem|
|
|
19
19
|
gem.add_development_dependency "rake"
|
20
20
|
gem.add_development_dependency "pry"
|
21
21
|
gem.add_development_dependency "pry-nav"
|
22
|
+
gem.add_development_dependency "rspec"
|
22
23
|
|
23
24
|
if RUBY_VERSION < "1.9"
|
24
25
|
gem.add_dependency "nokogiri", "~> 1.5.10"
|
data/lib/git-whistles/version.rb
CHANGED
data/libexec/git-merge-po.sh
CHANGED
@@ -1,26 +1,115 @@
|
|
1
1
|
#!/bin/sh
|
2
2
|
#
|
3
|
-
#
|
4
|
-
#
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
3
|
+
# Three-way merge driver for PO files
|
4
|
+
#
|
5
|
+
set -e
|
6
|
+
|
7
|
+
# failure handler
|
8
|
+
on_error() {
|
9
|
+
local parent_lineno="$1"
|
10
|
+
local message="$2"
|
11
|
+
local code="${3:-1}"
|
12
|
+
if [[ -n "$message" ]] ; then
|
13
|
+
echo "Error on or near line ${parent_lineno}: ${message}; exiting with status ${code}"
|
14
|
+
else
|
15
|
+
echo "Error on or near line ${parent_lineno}; exiting with status ${code}"
|
16
|
+
fi
|
17
|
+
exit 255
|
18
|
+
}
|
19
|
+
trap 'on_error ${LINENO}' ERR
|
20
|
+
|
21
|
+
# given a file, find the path that matches its contents
|
22
|
+
show_file() {
|
23
|
+
hash=`git hash-object "${1}"`
|
24
|
+
git ls-tree -r HEAD | fgrep "$hash" | cut -b54-
|
25
|
+
}
|
26
|
+
|
27
|
+
# wraps msgmerge with default options
|
28
|
+
function m_msgmerge() {
|
29
|
+
msgmerge --force-po --quiet --no-fuzzy-matching $@
|
30
|
+
}
|
31
|
+
|
32
|
+
# wraps msgcat with default options
|
33
|
+
function m_msgcat() {
|
34
|
+
msgcat --force-po $@
|
35
|
+
}
|
36
|
+
|
37
|
+
|
38
|
+
# removes the "graveyard strings" from the input
|
39
|
+
function strip_graveyard() {
|
40
|
+
sed -e '/^#~/d'
|
41
|
+
}
|
42
|
+
|
43
|
+
# select messages with a conflict marker
|
44
|
+
# pass -v to inverse selection
|
45
|
+
function grep_conflicts() {
|
46
|
+
msggrep $@ --msgstr -F -e '#-#-#' -
|
47
|
+
}
|
48
|
+
|
49
|
+
# select messages from $1 that are also in $2 but whose contents have changed
|
50
|
+
function extract_changes() {
|
51
|
+
msgcat -o - $1 $2 \
|
52
|
+
| grep_conflicts \
|
53
|
+
| m_msgmerge -o - $1 - \
|
54
|
+
| strip_graveyard
|
55
|
+
}
|
56
|
+
|
57
|
+
|
58
|
+
BASE=$1
|
59
|
+
LOCAL=$2
|
60
|
+
REMOTE=$3
|
61
|
+
OUTPUT=$LOCAL
|
62
|
+
TEMP=`mktemp /tmp/merge-po.XXXX`
|
63
|
+
|
64
|
+
echo "Using custom PO merge driver (`show_file ${LOCAL}`; $TEMP)"
|
10
65
|
|
11
66
|
# Extract the PO header from the current branch (top of file until first empty line)
|
12
|
-
|
13
|
-
|
67
|
+
sed -e '/^$/q' < $LOCAL > ${TEMP}.header
|
68
|
+
|
69
|
+
# clean input files
|
70
|
+
msguniq --force-po -o ${TEMP}.base --unique ${BASE}
|
71
|
+
msguniq --force-po -o ${TEMP}.local --unique ${LOCAL}
|
72
|
+
msguniq --force-po -o ${TEMP}.remote --unique ${REMOTE}
|
73
|
+
|
74
|
+
# messages changed on local
|
75
|
+
extract_changes ${TEMP}.local ${TEMP}.base > ${TEMP}.local-changes
|
76
|
+
|
77
|
+
# messages changed on remote
|
78
|
+
extract_changes ${TEMP}.remote ${TEMP}.base > ${TEMP}.remote-changes
|
79
|
+
|
80
|
+
# unchanged messages
|
81
|
+
m_msgcat -o - ${TEMP}.base ${TEMP}.local ${TEMP}.remote \
|
82
|
+
| grep_conflicts -v \
|
83
|
+
> ${TEMP}.unchanged
|
14
84
|
|
15
|
-
#
|
16
|
-
|
17
|
-
|
18
|
-
|
85
|
+
# messages changed on both local and remote (conflicts)
|
86
|
+
m_msgcat -o - ${TEMP}.remote-changes ${TEMP}.local-changes \
|
87
|
+
| grep_conflicts \
|
88
|
+
> ${TEMP}.conflicts
|
19
89
|
|
20
|
-
#
|
21
|
-
|
90
|
+
# messages changed on local, not on remote; and vice-versa
|
91
|
+
m_msgcat -o ${TEMP}.local-only --unique ${TEMP}.local-changes ${TEMP}.conflicts
|
92
|
+
m_msgcat -o ${TEMP}.remote-only --unique ${TEMP}.remote-changes ${TEMP}.conflicts
|
22
93
|
|
23
|
-
#
|
24
|
-
|
25
|
-
|
94
|
+
# the big merge
|
95
|
+
m_msgcat -o ${TEMP}.merge1 ${TEMP}.unchanged ${TEMP}.conflicts ${TEMP}.local-only ${TEMP}.remote-only
|
96
|
+
|
97
|
+
# create a template to filter messages actually needed (those on local and remote)
|
98
|
+
m_msgcat -o - ${TEMP}.local ${TEMP}.remote \
|
99
|
+
| m_msgmerge -o ${TEMP}.merge2 ${TEMP}.merge1 -
|
100
|
+
|
101
|
+
# final merge, adds saved header
|
102
|
+
m_msgcat -o ${TEMP}.merge3 --use-first ${TEMP}.header ${TEMP}.merge2
|
103
|
+
|
104
|
+
# produce output file (overwrites input LOCAL file)
|
105
|
+
cat ${TEMP}.merge3 > $OUTPUT
|
106
|
+
|
107
|
+
# check for conflicts
|
108
|
+
if grep '#-#' $OUTPUT > /dev/null ; then
|
109
|
+
echo "Conflict(s) detected"
|
110
|
+
echo " between ${TEMP}.local and ${TEMP}.remote"
|
111
|
+
exit 1
|
112
|
+
fi
|
113
|
+
rm -f ${TEMP}*
|
26
114
|
exit 0
|
115
|
+
|
data/spec/data/base.po
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
msgid ""
|
2
|
+
msgstr ""
|
3
|
+
"Project-Id-Version: Base header\n"
|
4
|
+
"Content-Type: text/plain; charset=UTF-8\n"
|
5
|
+
|
6
|
+
msgid "This little piggie is unchanged"
|
7
|
+
msgstr "1"
|
8
|
+
|
9
|
+
msgid "This little piggie is removed from remote, unchanged on local"
|
10
|
+
msgstr "2"
|
11
|
+
|
12
|
+
msgid "This little piggie is removed from remote, changed on local"
|
13
|
+
msgstr "3"
|
14
|
+
|
15
|
+
msgid "This little piggie is removed from local, unchanged on remote"
|
16
|
+
msgstr "4"
|
17
|
+
|
18
|
+
msgid "This little piggie is removed from local, changed on remote"
|
19
|
+
msgstr "5"
|
20
|
+
|
21
|
+
msgid "This little piggie is changed on local, unchanged on remote"
|
22
|
+
msgstr "6"
|
23
|
+
|
24
|
+
msgid "This little piggie is changed on remote, unchanged on local"
|
25
|
+
msgstr "7"
|
26
|
+
|
27
|
+
msgid "This little piggie is changed on remote and local"
|
28
|
+
msgstr "8"
|
29
|
+
|
30
|
+
# msgid "This little piggie is added on remote, not on local"
|
31
|
+
# msgstr "9"
|
32
|
+
#
|
33
|
+
# msgid "This little piggie is added on local, not on remote"
|
34
|
+
# msgstr "10"
|
35
|
+
#
|
36
|
+
# msgid "This little piggie is added on local and remote, with different values"
|
37
|
+
# msgstr "11"
|
38
|
+
|
data/spec/data/local.po
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
msgid ""
|
2
|
+
msgstr ""
|
3
|
+
"Project-Id-Version: Local header\n"
|
4
|
+
"Content-Type: text/plain; charset=UTF-8\n"
|
5
|
+
|
6
|
+
msgid "This little piggie is unchanged"
|
7
|
+
msgstr "1"
|
8
|
+
|
9
|
+
msgid "This little piggie is removed from remote, unchanged on local"
|
10
|
+
msgstr "2"
|
11
|
+
|
12
|
+
msgid "This little piggie is removed from remote, changed on local"
|
13
|
+
msgstr "3.local"
|
14
|
+
|
15
|
+
# msgid "This little piggie is removed from local, unchanged on remote"
|
16
|
+
# msgstr "4"
|
17
|
+
|
18
|
+
# msgid "This little piggie is removed from local, changed on remote"
|
19
|
+
# msgstr "5"
|
20
|
+
|
21
|
+
msgid "This little piggie is changed on local, unchanged on remote"
|
22
|
+
msgstr "6.local"
|
23
|
+
|
24
|
+
msgid "This little piggie is changed on remote, unchanged on local"
|
25
|
+
msgstr "7"
|
26
|
+
|
27
|
+
msgid "This little piggie is changed on remote and local"
|
28
|
+
msgstr "8.local"
|
29
|
+
|
30
|
+
# msgid "This little piggie is added on remote, not on local"
|
31
|
+
# msgstr "9"
|
32
|
+
|
33
|
+
msgid "This little piggie is added on local, not on remote"
|
34
|
+
msgstr "10.local"
|
35
|
+
|
36
|
+
msgid "This little piggie is added on local and remote, with different values"
|
37
|
+
msgstr "11.local"
|
38
|
+
|
39
|
+
|
data/spec/data/remote.po
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
msgid ""
|
2
|
+
msgstr ""
|
3
|
+
"Project-Id-Version: Remote header\n"
|
4
|
+
"Content-Type: text/plain; charset=UTF-8\n"
|
5
|
+
|
6
|
+
msgid "This little piggie is unchanged"
|
7
|
+
msgstr "1"
|
8
|
+
|
9
|
+
# msgid "This little piggie is removed from remote, unchanged on local"
|
10
|
+
# msgstr "2"
|
11
|
+
|
12
|
+
# msgid "This little piggie is removed from remote, changed on local"
|
13
|
+
# msgstr "3"
|
14
|
+
|
15
|
+
msgid "This little piggie is removed from local, unchanged on remote"
|
16
|
+
msgstr "4"
|
17
|
+
|
18
|
+
msgid "This little piggie is removed from local, changed on remote"
|
19
|
+
msgstr "5.remote"
|
20
|
+
|
21
|
+
msgid "This little piggie is changed on local, unchanged on remote"
|
22
|
+
msgstr "6"
|
23
|
+
|
24
|
+
msgid "This little piggie is changed on remote, unchanged on local"
|
25
|
+
msgstr "7.remote"
|
26
|
+
|
27
|
+
msgid "This little piggie is changed on remote and local"
|
28
|
+
msgstr "8.remote"
|
29
|
+
|
30
|
+
msgid "This little piggie is added on remote, not on local"
|
31
|
+
msgstr "9.remote"
|
32
|
+
|
33
|
+
# msgid "This little piggie is added on local, not on remote"
|
34
|
+
# msgstr "10"
|
35
|
+
|
36
|
+
msgid "This little piggie is added on local and remote, with different values"
|
37
|
+
msgstr "11.remote"
|
38
|
+
|
39
|
+
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'tempfile'
|
2
|
+
require 'pry'
|
3
|
+
|
4
|
+
def example_title
|
5
|
+
RSpec.current_example.description
|
6
|
+
end
|
7
|
+
|
8
|
+
# a trivial PO file loader. returns a hash.
|
9
|
+
def load_po(data)
|
10
|
+
h = {}
|
11
|
+
state = :none # :id, :str
|
12
|
+
id = ""
|
13
|
+
str = ""
|
14
|
+
(data.split("\n") + ['']).each do |line|
|
15
|
+
|
16
|
+
case state
|
17
|
+
when :none
|
18
|
+
next if line =~ /^$|^#/
|
19
|
+
fail unless line =~ /^msgid "(.*)"$/
|
20
|
+
id = $1
|
21
|
+
state = :id
|
22
|
+
when :id
|
23
|
+
if line =~ /^msgstr "(.*)"/
|
24
|
+
state = :str
|
25
|
+
str = $1
|
26
|
+
next
|
27
|
+
end
|
28
|
+
fail unless line =~ /^"(.*)"$/
|
29
|
+
id += $1
|
30
|
+
when :str
|
31
|
+
if line =~ /^$|^#/
|
32
|
+
state = :none
|
33
|
+
h[id] = str
|
34
|
+
next
|
35
|
+
end
|
36
|
+
fail unless line =~ /^"(.*)"$/
|
37
|
+
str += $1
|
38
|
+
end
|
39
|
+
end
|
40
|
+
h
|
41
|
+
end
|
42
|
+
|
43
|
+
describe 'git merge-po' do
|
44
|
+
subject do
|
45
|
+
f_local = Tempfile.new('spec')
|
46
|
+
f_base = Tempfile.new('spec')
|
47
|
+
f_remote = Tempfile.new('spec')
|
48
|
+
|
49
|
+
f_local.write File.read('spec/data/local.po')
|
50
|
+
f_base.write File.read('spec/data/base.po')
|
51
|
+
f_remote.write File.read('spec/data/remote.po')
|
52
|
+
|
53
|
+
f_local.flush
|
54
|
+
f_base.flush
|
55
|
+
f_remote.flush
|
56
|
+
|
57
|
+
system "./libexec/git-merge-po.sh #{f_base.path} #{f_local.path} #{f_remote.path}"
|
58
|
+
|
59
|
+
data = f_local.tap(&:rewind).read
|
60
|
+
# Uncomment to get a readable output file:
|
61
|
+
# File.open('spec/data/output.po', 'w') { |io| io.write data }
|
62
|
+
|
63
|
+
load_po(data)
|
64
|
+
end
|
65
|
+
|
66
|
+
{
|
67
|
+
"This little piggie is unchanged" => '1',
|
68
|
+
"This little piggie is removed from remote, unchanged on local" => '2',
|
69
|
+
"This little piggie is removed from remote, changed on local" => '3.local',
|
70
|
+
"This little piggie is removed from local, unchanged on remote" => '4',
|
71
|
+
"This little piggie is removed from local, changed on remote" => '5.remote',
|
72
|
+
"This little piggie is changed on local, unchanged on remote" => '6.local',
|
73
|
+
"This little piggie is changed on remote, unchanged on local" => '7.remote',
|
74
|
+
"This little piggie is added on remote, not on local" => '9.remote',
|
75
|
+
"This little piggie is added on local, not on remote" => '10.local'
|
76
|
+
}.each_pair do |piggie, value|
|
77
|
+
it piggie do
|
78
|
+
expect(subject[piggie]).to eq(value)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'This little piggie is changed on remote and local' do
|
83
|
+
value = subject[example_title]
|
84
|
+
expect(value).to include('8.local')
|
85
|
+
expect(value).to include('8.remote')
|
86
|
+
expect(value).to include('#-#-#')
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'This little piggie is added on local and remote, with different values' do
|
90
|
+
value = subject[example_title]
|
91
|
+
expect(value).to include('11.local')
|
92
|
+
expect(value).to include('11.remote')
|
93
|
+
expect(value).to include('#-#-#')
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# The generated `.rspec` file contains `--require spec_helper` which will cause
|
4
|
+
# this file to always be loaded, without a need to explicitly require it in any
|
5
|
+
# files.
|
6
|
+
#
|
7
|
+
# Given that it is always loaded, you are encouraged to keep this file as
|
8
|
+
# light-weight as possible. Requiring heavyweight dependencies from this file
|
9
|
+
# will add to the boot time of your test suite on EVERY test run, even for an
|
10
|
+
# individual file that may not need all of that loaded. Instead, consider making
|
11
|
+
# a separate helper file that requires the additional dependencies and performs
|
12
|
+
# the additional setup, and require it from the spec files that actually need
|
13
|
+
# it.
|
14
|
+
#
|
15
|
+
# The `.rspec` file also contains a few flags that are not defaults but that
|
16
|
+
# users commonly want.
|
17
|
+
#
|
18
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
19
|
+
RSpec.configure do |config|
|
20
|
+
# rspec-expectations config goes here. You can use an alternate
|
21
|
+
# assertion/expectation library such as wrong or the stdlib/minitest
|
22
|
+
# assertions if you prefer.
|
23
|
+
config.expect_with :rspec do |expectations|
|
24
|
+
# This option will default to `true` in RSpec 4. It makes the `description`
|
25
|
+
# and `failure_message` of custom matchers include text for helper methods
|
26
|
+
# defined using `chain`, e.g.:
|
27
|
+
# be_bigger_than(2).and_smaller_than(4).description
|
28
|
+
# # => "be bigger than 2 and smaller than 4"
|
29
|
+
# ...rather than:
|
30
|
+
# # => "be bigger than 2"
|
31
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
32
|
+
end
|
33
|
+
|
34
|
+
# rspec-mocks config goes here. You can use an alternate test double
|
35
|
+
# library (such as bogus or mocha) by changing the `mock_with` option here.
|
36
|
+
config.mock_with :rspec do |mocks|
|
37
|
+
# Prevents you from mocking or stubbing a method that does not exist on
|
38
|
+
# a real object. This is generally recommended, and will default to
|
39
|
+
# `true` in RSpec 4.
|
40
|
+
mocks.verify_partial_doubles = true
|
41
|
+
end
|
42
|
+
|
43
|
+
# The settings below are suggested to provide a good initial experience
|
44
|
+
# with RSpec, but feel free to customize to your heart's content.
|
45
|
+
=begin
|
46
|
+
# These two settings work together to allow you to limit a spec run
|
47
|
+
# to individual examples or groups you care about by tagging them with
|
48
|
+
# `:focus` metadata. When nothing is tagged with `:focus`, all examples
|
49
|
+
# get run.
|
50
|
+
config.filter_run :focus
|
51
|
+
config.run_all_when_everything_filtered = true
|
52
|
+
|
53
|
+
# Limits the available syntax to the non-monkey patched syntax that is
|
54
|
+
# recommended. For more details, see:
|
55
|
+
# - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
|
56
|
+
# - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
|
57
|
+
# - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
|
58
|
+
config.disable_monkey_patching!
|
59
|
+
|
60
|
+
# This setting enables warnings. It's recommended, but in some cases may
|
61
|
+
# be too noisy due to issues in dependencies.
|
62
|
+
config.warnings = true
|
63
|
+
|
64
|
+
# Many RSpec users commonly either run the entire suite or an individual
|
65
|
+
# file, and it's useful to allow more verbose output when running an
|
66
|
+
# individual spec file.
|
67
|
+
if config.files_to_run.one?
|
68
|
+
# Use the documentation formatter for detailed output,
|
69
|
+
# unless a formatter has already been configured
|
70
|
+
# (e.g. via a command-line flag).
|
71
|
+
config.default_formatter = 'doc'
|
72
|
+
end
|
73
|
+
|
74
|
+
# Print the 10 slowest examples and example groups at the
|
75
|
+
# end of the spec run, to help surface which specs are running
|
76
|
+
# particularly slow.
|
77
|
+
config.profile_examples = 10
|
78
|
+
|
79
|
+
# Run specs in random order to surface order dependencies. If you find an
|
80
|
+
# order dependency and want to debug it, you can fix the order by providing
|
81
|
+
# the seed, which is printed after each run.
|
82
|
+
# --seed 1234
|
83
|
+
config.order = :random
|
84
|
+
|
85
|
+
# Seed global randomization in this process using the `--seed` CLI option.
|
86
|
+
# Setting this allows you to use `--seed` to deterministically reproduce
|
87
|
+
# test failures related to randomization by passing the same `--seed` value
|
88
|
+
# as the one that triggered the failure.
|
89
|
+
Kernel.srand config.seed
|
90
|
+
=end
|
91
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: git-whistles
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Julien Letessier
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2015-04-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -67,6 +67,20 @@ dependencies:
|
|
67
67
|
- - ">="
|
68
68
|
- !ruby/object:Gem::Version
|
69
69
|
version: '0'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: rspec
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
70
84
|
- !ruby/object:Gem::Dependency
|
71
85
|
name: pivotal-tracker
|
72
86
|
requirement: !ruby/object:Gem::Requirement
|
@@ -115,6 +129,7 @@ extensions: []
|
|
115
129
|
extra_rdoc_files: []
|
116
130
|
files:
|
117
131
|
- ".gitignore"
|
132
|
+
- ".rspec"
|
118
133
|
- Gemfile
|
119
134
|
- Gemfile.lock
|
120
135
|
- HISTORY
|
@@ -144,6 +159,11 @@ files:
|
|
144
159
|
- libexec/git-merge-po.sh
|
145
160
|
- libexec/git-stash-and-checkout.sh
|
146
161
|
- libexec/runner.rb
|
162
|
+
- spec/data/base.po
|
163
|
+
- spec/data/local.po
|
164
|
+
- spec/data/remote.po
|
165
|
+
- spec/git_merge_po_spec.rb
|
166
|
+
- spec/spec_helper.rb
|
147
167
|
homepage: http://github.com/mezis/git-whistles
|
148
168
|
licenses:
|
149
169
|
- MIT
|
@@ -164,9 +184,15 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
164
184
|
version: 1.3.6
|
165
185
|
requirements: []
|
166
186
|
rubyforge_project:
|
167
|
-
rubygems_version: 2.
|
187
|
+
rubygems_version: 2.4.5
|
168
188
|
signing_key:
|
169
189
|
specification_version: 4
|
170
190
|
summary: 'A few helpers for classic Git workflows: makes branching and merging, PO
|
171
191
|
file handling, issuing pull requests slightly simpler.'
|
172
|
-
test_files:
|
192
|
+
test_files:
|
193
|
+
- spec/data/base.po
|
194
|
+
- spec/data/local.po
|
195
|
+
- spec/data/remote.po
|
196
|
+
- spec/git_merge_po_spec.rb
|
197
|
+
- spec/spec_helper.rb
|
198
|
+
has_rdoc:
|