git-whistles 0.3.0

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 ADDED
@@ -0,0 +1,9 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ pkg
8
+ rdoc
9
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in /tmp/git-whistles.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Julien Letessier
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ 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.
data/README.md ADDED
@@ -0,0 +1,73 @@
1
+ This repository is about sharing helper scripts for the [Git](http://git-scm.com/)
2
+ version control system.
3
+
4
+ Install with:
5
+
6
+ git clone git://github.com/mezis/git-whistles.git <clone-dir>
7
+
8
+ Add `<clone-dir>/bin` to your `$PATH`
9
+
10
+
11
+ #### chop
12
+
13
+ `git chop [branch]`
14
+
15
+ Delete the local and origin copy of a branch.
16
+ Useful to close feature branches once a feature is completed.
17
+
18
+ #### list-branches
19
+
20
+
21
+ `git list-branches [-l] [-r] [-i integration-branch]`
22
+
23
+ Colourful listing of all local or origin branches, and their distance to an
24
+ integration branch (`master` by default).
25
+
26
+ #### merge-po
27
+
28
+ `git merge-po <ancestor> <left> <right>`
29
+
30
+ For those using `gettext` for I18n, a must-have: this custom merge driver
31
+ will handle most merge/conflicts issues when a PO file was edited by different
32
+ committers.
33
+
34
+ You don't have to call this directly.
35
+
36
+ Add this to your .git/config:
37
+
38
+ [merge "pofile"]
39
+ name = Gettext merge driver
40
+ driver = git merge-po %O %A %B
41
+
42
+ Add this to .gitattributes:
43
+
44
+ *.po merge=pofile
45
+ *.pot merge=pofile
46
+
47
+
48
+ #### pull-request
49
+
50
+ `git-pull-request [branch]`
51
+
52
+ Open your browser at a Github pull-request page for the specified branch
53
+ (defaults to the current `head`).
54
+
55
+
56
+ #### stash-and-checkout
57
+
58
+ `git stash-and-checkout [branch]`
59
+
60
+ As the name implies: stash and checkout another branch.
61
+ If there was work in progress previously stashes for the target branch, it gets
62
+ unstashed.
63
+
64
+ This lets you keep work in progress on multiple branches without committing it.
65
+
66
+ I tend to alias this to `git co`.
67
+
68
+
69
+ ## outstanding-features
70
+
71
+ `git checkout production ; git outstanding-features`
72
+
73
+ Lists the merge pull-requests that are on `production` but not (yet) on `origin/production`.
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
data/bin/git-chop ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # runner.rb --
4
+ #
5
+ # Run shell scripts from a gem.
6
+ # Symlink to this script to run a script with the same name living in
7
+ # libexec/.
8
+ #
9
+ require 'pathname'
10
+ require 'rubygems'
11
+ require 'git-whistles'
12
+
13
+ target_script = Pathname.new($0).basename
14
+ script_path = Git::Whistles::GEMDIR.join('libexec', "#{target_script}.sh").cleanpath
15
+
16
+ Kernel.exec script_path, *ARGV
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # runner.rb --
4
+ #
5
+ # Run shell scripts from a gem.
6
+ # Symlink to this script to run a script with the same name living in
7
+ # libexec/.
8
+ #
9
+ require 'pathname'
10
+ require 'rubygems'
11
+ require 'git-whistles'
12
+
13
+ target_script = Pathname.new($0).basename
14
+ script_path = Git::Whistles::GEMDIR.join('libexec', "#{target_script}.sh").cleanpath
15
+
16
+ Kernel.exec script_path, *ARGV
data/bin/git-merge-po ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # runner.rb --
4
+ #
5
+ # Run shell scripts from a gem.
6
+ # Symlink to this script to run a script with the same name living in
7
+ # libexec/.
8
+ #
9
+ require 'pathname'
10
+ require 'rubygems'
11
+ require 'git-whistles'
12
+
13
+ target_script = Pathname.new($0).basename
14
+ script_path = Git::Whistles::GEMDIR.join('libexec', "#{target_script}.sh").cleanpath
15
+
16
+ Kernel.exec script_path, *ARGV
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # runner.rb --
4
+ #
5
+ # Run shell scripts from a gem.
6
+ # Symlink to this script to run a script with the same name living in
7
+ # libexec/.
8
+ #
9
+ require 'pathname'
10
+ require 'rubygems'
11
+ require 'git-whistles'
12
+
13
+ target_script = Pathname.new($0).basename
14
+ script_path = Git::Whistles::GEMDIR.join('libexec', "#{target_script}.sh").cleanpath
15
+
16
+ Kernel.exec script_path, *ARGV
@@ -0,0 +1,53 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # git-pull-request --
4
+ #
5
+ # Open a pull request for the current branch in your default browser
6
+ #
7
+ # Copyright (C) 2012 Julien Letessier
8
+ #
9
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
10
+ # this software and associated documentation files (the "Software"), to deal in
11
+ # the Software without restriction, including without limitation the rights to
12
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
13
+ # of the Software, and to permit persons to whom the Software is furnished to do
14
+ # so, subject to the following conditions:
15
+ #
16
+ # The above copyright notice and this permission notice shall be included in all
17
+ # copies or substantial portions of the Software.
18
+ #
19
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ # SOFTWARE.
26
+ #
27
+ require 'CGI'
28
+
29
+ origin_url = `git config --get remote.origin.url`.strip
30
+ unless origin_url =~ /github\.com/
31
+ puts "origin does not have a Github URL !"
32
+ exit 1
33
+ end
34
+
35
+ repo = origin_url.sub(/.*github\.com[\/:]/,'').sub(/\.git$/,'')
36
+
37
+ if ARGV[0]
38
+ branch = ARGV[0]
39
+ else
40
+ branch = `git symbolic-ref HEAD`.gsub(%r(^refs/heads/), "")
41
+ exit $? unless $? == 0
42
+ end
43
+
44
+ if branch == 'master'
45
+ puts "You cannot issue a pull request for master !"
46
+ exit 1
47
+ end
48
+
49
+ against = ARGV[1] || 'master'
50
+
51
+ url = "https://github.com/#{repo}/pull/new?base_repo=#{CGI.escape(repo)}&base_ref=#{against}&head_ref=#{branch}"
52
+ puts "Preparing a pull request for branch #{branch}"
53
+ system "open", url
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # runner.rb --
4
+ #
5
+ # Run shell scripts from a gem.
6
+ # Symlink to this script to run a script with the same name living in
7
+ # libexec/.
8
+ #
9
+ require 'pathname'
10
+ require 'rubygems'
11
+ require 'git-whistles'
12
+
13
+ target_script = Pathname.new($0).basename
14
+ script_path = Git::Whistles::GEMDIR.join('libexec', "#{target_script}.sh").cleanpath
15
+
16
+ Kernel.exec script_path, *ARGV
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/git-whistles/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Julien Letessier"]
6
+ gem.email = ["julien.letessier@gmail.com"]
7
+ gem.description = %q{A few helpers for classic Git workflows}
8
+ gem.summary = %q{
9
+ A few helpers for classic Git workflows:
10
+ makes branching and merging, PO file handling, issuing pull requests
11
+ slightly simpler.
12
+ }
13
+ gem.homepage = "http://github.com/mezis/git-whistles"
14
+
15
+ gem.required_rubygems_version = ">= 1.3.6"
16
+
17
+ gem.add_development_dependency "bundler", ">= 1.0.0"
18
+ gem.add_development_dependency "rake"
19
+
20
+ gem.files = `git ls-files`.split($\)
21
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
22
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
23
+ gem.name = "git-whistles"
24
+ gem.require_paths = ["lib"]
25
+ gem.version = Git::Whistles::VERSION
26
+ end
@@ -0,0 +1,8 @@
1
+ require 'pathname'
2
+
3
+ module Git
4
+ module Whistles
5
+ VERSION = "0.3.0"
6
+ GEMDIR = Pathname.new(__FILE__).parent.parent.parent
7
+ end
8
+ end
@@ -0,0 +1,6 @@
1
+ require "git-whistles/version"
2
+
3
+ module Git
4
+ module Whistles
5
+ end
6
+ end
@@ -0,0 +1,44 @@
1
+ #!/bin/bash
2
+ #
3
+ # git-chop --
4
+ #
5
+ # Close a feature branch - removing it from local and remote.
6
+ #
7
+ # Copyright (C) 2012 Julien Letessier
8
+ #
9
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
10
+ # this software and associated documentation files (the "Software"), to deal in
11
+ # the Software without restriction, including without limitation the rights to
12
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
13
+ # of the Software, and to permit persons to whom the Software is furnished to do
14
+ # so, subject to the following conditions:
15
+ #
16
+ # The above copyright notice and this permission notice shall be included in all
17
+ # copies or substantial portions of the Software.
18
+ #
19
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ # SOFTWARE.
26
+ #
27
+
28
+ die() {
29
+ echo "$@" ; exit 1
30
+ }
31
+
32
+ head=$(git symbolic-ref HEAD 2> /dev/null || git log -1 --format=%h)
33
+ current_branch=${head#refs/heads/}
34
+
35
+ branch="$1"
36
+ : ${branch:-$head}
37
+ echo "Closing feature branch $branch"
38
+
39
+ if [ "$branch" = "$current_branch" ] ; then
40
+ git checkout master || die
41
+ fi
42
+
43
+ git branch -d "$branch" || die
44
+ git push origin ":$branch" || die
@@ -0,0 +1,165 @@
1
+ #!/bin/bash
2
+ #
3
+ # git-list-branches --
4
+ #
5
+ # List branch status and age against an integration branch.
6
+ #
7
+ # Copyright (C) 2012 Julien Letessier
8
+ #
9
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
10
+ # this software and associated documentation files (the "Software"), to deal in
11
+ # the Software without restriction, including without limitation the rights to
12
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
13
+ # of the Software, and to permit persons to whom the Software is furnished to do
14
+ # so, subject to the following conditions:
15
+ #
16
+ # The above copyright notice and this permission notice shall be included in all
17
+ # copies or substantial portions of the Software.
18
+ #
19
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ # SOFTWARE.
26
+ #
27
+ PROGNAME=$(basename $0)
28
+
29
+
30
+ _has_git() {
31
+ git rev-parse head > /dev/null 2>&1
32
+ }
33
+
34
+ _check_branches_format() {
35
+ if [ $porcelain = no ] ; then
36
+ echo "%-70s +%-6s -%-6s %-18s %s\n"
37
+ else
38
+ echo "%s,%s,%s,%s,%s\n"
39
+ fi
40
+ }
41
+
42
+ _xterm_color() {
43
+ color=$(( 16 + ($1 * 36) + ($2 * 6) + $3 ))
44
+ case $4 in
45
+ (bg) code=48 ;;
46
+ (*) code=38 ;;
47
+ esac
48
+ echo "\033[${code};5;${color}m"
49
+ }
50
+
51
+ _xterm_escape() {
52
+ echo "\033[$1m"
53
+ }
54
+
55
+ _list_branches() {
56
+ case $1 in
57
+ remote)
58
+ git show-ref | fgrep remotes/origin | sed -e 's:.*remotes/::'
59
+ ;;
60
+ local)
61
+ git show-ref --heads | sed -e 's:.*refs/heads/::'
62
+ ;;
63
+ esac
64
+ }
65
+
66
+ _check_branch() {
67
+ branch=$1
68
+ against=$2
69
+ ahead=$(git rev-list --abbrev-commit $branch ^$against | wc -l)
70
+ behind=$(git rev-list --abbrev-commit $against ^$branch | wc -l)
71
+ stamp=$(_rev_stamp $branch)
72
+ if [ $behind -gt 0 ] ; then
73
+ behind_last=$(git rev-list --reverse $against ^$branch | head -1)
74
+ behind_by=$(_rev_age $behind_last)
75
+ else
76
+ behind_by=""
77
+ fi
78
+
79
+ branch_latest=$(git rev-list -n 1 $branch)
80
+ who=$(_rev_author $branch_latest)
81
+
82
+ printf "$(_check_branches_format)" $branch $ahead $behind "$behind_by" "$who"
83
+ }
84
+
85
+ _rev_age() {
86
+ git log -1 --format='%ar' $1
87
+ }
88
+
89
+ _rev_stamp() {
90
+ git log -1 --format='%at' $1
91
+ }
92
+
93
+ _rev_author() {
94
+ git log -1 --format='%an' $1
95
+ }
96
+
97
+ _check_all_branches() {
98
+ for branch in $(_list_branches $1) ; do
99
+ _check_branch $branch $2
100
+ done
101
+ }
102
+
103
+ _color_by_duration() {
104
+ while read LINE ; do
105
+ case "$LINE" in
106
+ (*+0*) color=$(_xterm_color 1 1 1) ;;
107
+ (*minute*) color=$(_xterm_color 0 5 0) ;;
108
+ (*hour*) color=$(_xterm_color 0 5 0) ;;
109
+ (*days*) color=$(_xterm_color 5 5 0) ;;
110
+ (*week*) color=$(_xterm_color 5 3 0) ;;
111
+ (*month*) color=$(_xterm_color 5 0 0) ;;
112
+ (*year*) color=$(_xterm_color 4 0 0) ;;
113
+ (*) color=$(_xterm_escape 0) ;;
114
+ esac
115
+ normal=$(_xterm_escape 0)
116
+ printf "${color}${LINE}${normal}\n"
117
+ # echo "$LINE"
118
+ done
119
+ }
120
+
121
+ _usage() {
122
+ echo
123
+ echo "$(basename $0) [-l] [-r] [-i integration-branch]"
124
+ echo
125
+ echo " -l : show local branches (default)"
126
+ echo " -r : show remote branches"
127
+ echo " -i [branch] : integration branch, defaults to 'origin/master'"
128
+ }
129
+
130
+ _die() {
131
+ echo "$@" >&2
132
+ exit 1
133
+ }
134
+
135
+ while getopts hprli: opt ; do
136
+ case $opt in
137
+ h) _usage ; exit 0 ;;
138
+ p) porcelain="yes" ;;
139
+ l) where="local" ;;
140
+ r) where="remote" ;;
141
+ i) against="$OPTARG" ;;
142
+ \?) _die ;;
143
+ :) _die "Option -$OPTARG requires an argument." ;;
144
+ *) echo "argument $OPTARG" ;;
145
+ esac
146
+ done
147
+ shift $((OPTIND-1))
148
+
149
+ [ $# -gt 0 ] && _usage && _die "Too many arguments."
150
+
151
+ _has_git || die "Not in a git repository !"
152
+
153
+ : ${porcelain:=no}
154
+ : ${where:=local}
155
+ : ${against:=origin/master}
156
+
157
+ if [ $porcelain = no ] ; then
158
+ echo "Listing $where branches against $against"
159
+ printf "$(_check_branches_format)" "BRANCH NAME" "AHEAD" "BEHIND" "OLDEST UNPULLED" "AUTHOR"
160
+ _check_all_branches $where $against | _color_by_duration
161
+ else
162
+ _check_all_branches $where $against
163
+ fi
164
+
165
+
@@ -0,0 +1,58 @@
1
+ #!/bin/sh
2
+ #
3
+ # git-merge-po --
4
+ #
5
+ # Custom Git merge driver - merges PO files using msgcat(1)
6
+ #
7
+ # - Add this to your .git/config :
8
+ #
9
+ # [merge "pofile"]
10
+ # name = Gettext merge driver
11
+ # driver = git merge-po %O %A %B
12
+ #
13
+ # - Add this to .gitattributes :
14
+ #
15
+ # *.po merge=pofile
16
+ # *.pot merge=pofile
17
+ #
18
+ # Copyright (C) 2012 Julien Letessier
19
+ #
20
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
21
+ # this software and associated documentation files (the "Software"), to deal in
22
+ # the Software without restriction, including without limitation the rights to
23
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
24
+ # of the Software, and to permit persons to whom the Software is furnished to do
25
+ # so, subject to the following conditions:
26
+ #
27
+ # The above copyright notice and this permission notice shall be included in all
28
+ # copies or substantial portions of the Software.
29
+ #
30
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
31
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
32
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
33
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
34
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
35
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
36
+ # SOFTWARE.
37
+ #
38
+ #
39
+ O=$1
40
+ A=$2
41
+ B=$3
42
+
43
+ # Extract the PO header from the current branch (top of file until first empty line)
44
+ header=$(mktemp /tmp/merge-po.XXXX)
45
+ sed -e '/^$/q' < $A > $header
46
+
47
+ # Merge files, then repair header
48
+ temp=$(mktemp /tmp/merge-po.XXXX)
49
+ msgcat -o $temp $A $B
50
+ msgcat --use-first -o $A $header $temp
51
+
52
+ # Clean up
53
+ rm $header $temp
54
+
55
+ # Check for conflicts
56
+ conflicts=$(grep -c "#-#" $A)
57
+ test $conflicts -gt 0 && exit 1
58
+ exit 0
@@ -0,0 +1,8 @@
1
+ #!/bin/sh
2
+
3
+ set -x
4
+
5
+ from=${1:-origin/production}
6
+ to=${2:-production}
7
+
8
+ git log --oneline ${to} ^${from} | grep 'Merge pull request' | sed -e 's:.*from [^/]*/::'
@@ -0,0 +1,45 @@
1
+ #!/bin/bash
2
+ #
3
+ # git-stash-and-checkout --
4
+ #
5
+ # Push to the stash, checkout, and pop the relevant WIP stash.
6
+ #
7
+ # Copyright (C) 2012 Julien Letessier
8
+ #
9
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
10
+ # this software and associated documentation files (the "Software"), to deal in
11
+ # the Software without restriction, including without limitation the rights to
12
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
13
+ # of the Software, and to permit persons to whom the Software is furnished to do
14
+ # so, subject to the following conditions:
15
+ #
16
+ # The above copyright notice and this permission notice shall be included in all
17
+ # copies or substantial portions of the Software.
18
+ #
19
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ # SOFTWARE.
26
+ #
27
+
28
+ die() {
29
+ echo "$@" ; exit 1
30
+ }
31
+
32
+ head=$(git symbolic-ref HEAD 2> /dev/null || git log -1 --format=%h)
33
+ current_branch=${head#refs/heads/}
34
+ target_branch=$1
35
+
36
+ git stash --include-untracked || die
37
+ git checkout $target_branch || die
38
+
39
+ stash=$(git stash list | grep "WIP on ${target_branch}:")
40
+ stash=${stash%%:*}
41
+
42
+ if test -n "$stash" ; then
43
+ echo "Popping $stash"
44
+ git stash pop $stash
45
+ fi
data/libexec/runner.rb ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # runner.rb --
4
+ #
5
+ # Run shell scripts from a gem.
6
+ # Symlink to this script to run a script with the same name living in
7
+ # libexec/.
8
+ #
9
+ require 'pathname'
10
+ require 'rubygems'
11
+ require 'git-whistles'
12
+
13
+ target_script = Pathname.new($0).basename
14
+ script_path = Git::Whistles::GEMDIR.join('libexec', "#{target_script}.sh").cleanpath
15
+
16
+ Kernel.exec script_path, *ARGV
metadata ADDED
@@ -0,0 +1,123 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: git-whistles
3
+ version: !ruby/object:Gem::Version
4
+ hash: 19
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 3
9
+ - 0
10
+ version: 0.3.0
11
+ platform: ruby
12
+ authors:
13
+ - Julien Letessier
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-08-26 00:00:00 +01:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ requirement: &id001 !ruby/object:Gem::Requirement
23
+ none: false
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ hash: 23
28
+ segments:
29
+ - 1
30
+ - 0
31
+ - 0
32
+ version: 1.0.0
33
+ prerelease: false
34
+ name: bundler
35
+ type: :development
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ prerelease: false
48
+ name: rake
49
+ type: :development
50
+ version_requirements: *id002
51
+ description: A few helpers for classic Git workflows
52
+ email:
53
+ - julien.letessier@gmail.com
54
+ executables:
55
+ - git-chop
56
+ - git-list-branches
57
+ - git-merge-po
58
+ - git-outstanding-features
59
+ - git-pull-request
60
+ - git-stash-and-checkout
61
+ extensions: []
62
+
63
+ extra_rdoc_files: []
64
+
65
+ files:
66
+ - .gitignore
67
+ - Gemfile
68
+ - LICENSE
69
+ - README.md
70
+ - Rakefile
71
+ - bin/git-chop
72
+ - bin/git-list-branches
73
+ - bin/git-merge-po
74
+ - bin/git-outstanding-features
75
+ - bin/git-pull-request
76
+ - bin/git-stash-and-checkout
77
+ - git-whistles.gemspec
78
+ - lib/git-whistles.rb
79
+ - lib/git-whistles/version.rb
80
+ - libexec/git-chop.sh
81
+ - libexec/git-list-branches.sh
82
+ - libexec/git-merge-po.sh
83
+ - libexec/git-outstanding-features.sh
84
+ - libexec/git-stash-and-checkout.sh
85
+ - libexec/runner.rb
86
+ has_rdoc: true
87
+ homepage: http://github.com/mezis/git-whistles
88
+ licenses: []
89
+
90
+ post_install_message:
91
+ rdoc_options: []
92
+
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ hash: 3
101
+ segments:
102
+ - 0
103
+ version: "0"
104
+ required_rubygems_version: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ hash: 23
110
+ segments:
111
+ - 1
112
+ - 3
113
+ - 6
114
+ version: 1.3.6
115
+ requirements: []
116
+
117
+ rubyforge_project:
118
+ rubygems_version: 1.3.9.5
119
+ signing_key:
120
+ specification_version: 3
121
+ summary: "A few helpers for classic Git workflows: makes branching and merging, PO file handling, issuing pull requests slightly simpler."
122
+ test_files: []
123
+