git-whistles 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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
+