↓ Skip to main content

Programming

Jupyter notebook with Bash kernel

·335 words·2 mins
Adding Bash to Tensorflow notebook # I commented out PHP and C++ stuff that I do not really need: FROM jupyter/tensorflow-notebook USER root # install dependencies RUN apt-get update && apt-get install -yq --no-install-recommends \ php-cli php-dev php-pear \ pkg-config \ && apt-get clean # rm -rf /var/lib/apt/lists/* # install zeromq and zmq php extension #RUN wget https://github.com/zeromq/zeromq4-1/releases/download/v4.1.5/zeromq-4.1.5.tar.gz && \ # tar -xvf zeromq-4.1.5.tar.gz && \ # cd zeromq-* && \ # ./configure && make && make install && \ # printf "\n" | pecl install zmq-beta && \ # echo "extension=zmq.so" > /etc/php/7.0/cli/conf.d/zmq.ini # install PHP composer #RUN wget https://getcomposer.org/installer -O composer-setup.php && \ # wget https://litipk.github.io/Jupyter-PHP-Installer/dist/jupyter-php-installer.phar && \ # php composer-setup.php && \ # php ./jupyter-php-installer.phar -vvv install && \ # mv composer.phar /usr/local/bin/composer && \ # rm -rf zeromq-* jupyter-php* && \ # rm composer-setup.php # install ijavascript #RUN apt-get install -yq nodejs npm libzmq3-dev node-gyp && \ # npm install -g ijavascript && \ # ijs --ijs-install=global #RUN cd .. && \ # apt-get install -yq --no-install-recommends cmake && \ # wget https://raw.githubusercontent.com/root-mirror/cling/master/tools/packaging/cpt.py && \ # chmod +x cpt.py && \ # ./cpt.py --check-requirements && ./cpt.py --create-dev-env Debug --with-workdir=./cling/ #RUN cd .. && \ # wget https://root.cern.ch/download/cling/cling_2017-09-15_ubuntu16.tar.bz2 && \ # tar -xvjf cling_2017-09-15_ubuntu16.tar.bz2 && \ # rm cling_*.tar.bz2 && \ # mv cling_* cling #RUN cd .. && \ # ln -s $(pwd)/cling/bin/* /usr/bin/ && \ # cd cling/share/cling/Jupyter/kernel && \ # pip install -e . && \ # jupyter-kernelspec install cling-cpp17 && \ # jupyter-kernelspec install cling-cpp14 && \ # jupyter-kernelspec install cling-cpp11 RUN chown -R $NB_USER /home/$NB_USER && \ rm -rf /home/$NB_USER/.local/share/jupyter # install java jre for h2o RUN apt-get install -yq openjdk-8-jre # Reset user from jupyter/base-notebook USER $NB_USER # install jupyter-bash RUN /opt/conda/bin/pip install --no-cache-dir bash_kernel RUN /opt/conda/bin/python -m bash_kernel.install # install h2o RUN /opt/conda/bin/pip install --no-cache-dir --upgrade h2o && \ /opt/conda/bin/pip install --no-cache-dir --upgrade pandas # disable authentication RUN mkdir -p .jupyter RUN echo "" >> ~/.jupyter/jupyter_notebook_config.py RUN echo "c.NotebookApp.token = ''" >> ~/.jupyter/jupyter_notebook_config.py Source: https://bitbucket.org/snippets/klassify/Ee9Myk/jupyter-notebook-with-bash-kernel

DockerCon 2018 - great event (with a small fly in the ointment)

·2039 words·10 mins
I have just returned from DockerCon Europe 2018 and I’d like to share my impressions while they are fresh in my mind. It was my first DockerCon so I was not quite sure what to expect. As the title says, it was great experience and barring the scaling issue (more below) could have been really awesome experience. But let’s take things in order. First location - Barcelona. Hard to pick better place in December than Spain. I am sure the Northerners greatly appreciated the break from cold and enjoyed the balmy 15 to 20 degrees. The venue Centre de Convencions Internacional de Barcelona - CCIB - though not located in the centre, is at the shore and one can walk to the beach in 2-3 minutes. There were three of us going from Valencia office (which is 3 hours train ride down the coast from Barcelona) and we had also great hotel experience. I can highly recommend Hotel Princess Barcelona. What can be better than starting your day with watching sunrise over Mediterranean Sea. Thanks David - because you did such a great job, you are now in charge of travel and hotel booking going forward :-D

ATG Module Diagram Generator

·302 words·2 mins
I have found local clone of this repo while cleaning up the disk. The source was originally residing in private repo on Bitbucket which I moved to GitHub: https://github.com/miroadamy/atgdiagram What it does # Groovy scripts: https://github.com/miroadamy/atgdiagram/blob/master/src/listATGModules.groovy https://github.com/miroadamy/atgdiagram/blob/master/src/ATGModule.groovy that scan local ATG installation, discover modules and generate the PlantUML file representing it, for example - https://github.com/miroadamy/atgdiagram/blob/master/uml/test2.uml Using ATG_ROOT from environment variable $ATG_ROOT: /opt/ATG/ATG10.0.2 Using /opt/ATG/ATG10.0.2 installation Dependants of module TWeStore.eStore => [DCS.Search.Query, B2CCommerce, DAF.Search.Query, DAF.Search.Base, DCS.Search.common, DPS.Search.Index, DAF.Search.common, DAS-UI, DCS.Search.Index, DPS, DCS, DCS.Search.CustomCatalogs, DCS.Search.CustomCatalogs.Query, DCS.Search.CustomCatalogs.Index, DAF.Search.Routing, DCS.Search.CustomCatalogs.common, DAF.Search.Index, DSS, DCS.CustomCatalogs, DAS] @startuml Object TWeStore_eStore Object DCS Object B2CCommerce Object DCS_Search_CustomCatalogs Object DAF_Search_Routing Object DCS_CustomCatalogs Object DPS Object DCS_Search_CustomCatalogs_Query Object DAF_Search_Base Object DCS_Search_CustomCatalogs_Index Object DSS Object DAS_UI Object DCS_Search_Query Object DCS_Search_CustomCatalogs_common Object DAS Object DCS_Search_Index Object DAF_Search_Query Object DCS_Search_common Object DPS_Search_Index Object DAF_Search_Index Object DAF_Search_common TWeStore_eStore <|-- DCS TWeStore_eStore <|-- DCS_CustomCatalogs TWeStore_eStore <|-- B2CCommerce TWeStore_eStore <|-- DCS_Search_CustomCatalogs TWeStore_eStore <|-- DAF_Search_Routing DCS <|-- DPS DCS <|-- DSS B2CCommerce <|-- DCS DCS_Search_CustomCatalogs <|-- DCS_Search_CustomCatalogs_Index DCS_Search_CustomCatalogs <|-- DCS_Search_CustomCatalogs_Query DAF_Search_Routing <|-- DAS_UI DAF_Search_Routing <|-- DAF_Search_Base DCS_CustomCatalogs <|-- DCS DPS <|-- DAS DCS_Search_CustomCatalogs_Query <|-- DCS_Search_Query DCS_Search_CustomCatalogs_Query <|-- DCS_Search_CustomCatalogs_common DAF_Search_Base <|-- DAS_UI DCS_Search_CustomCatalogs_Index <|-- DCS_Search_Index DCS_Search_CustomCatalogs_Index <|-- DCS_Search_CustomCatalogs_common DSS <|-- DPS DAS_UI <|-- DAS DCS_Search_Query <|-- DAF_Search_Query DCS_Search_Query <|-- DCS_Search_common DCS_Search_Query <|-- DCS DCS_Search_CustomCatalogs_common <|-- DCS_Search_common DCS_Search_CustomCatalogs_common <|-- DCS_CustomCatalogs DCS_Search_Index <|-- DPS_Search_Index DCS_Search_Index <|-- DCS_Search_common DCS_Search_Index <|-- DCS DAF_Search_Query <|-- DAF_Search_common DCS_Search_common <|-- DAF_Search_common DCS_Search_common <|-- DCS DPS_Search_Index <|-- DPS DPS_Search_Index <|-- DAF_Search_Index DAF_Search_Index <|-- DAS_UI DAF_Search_Index <|-- DAF_Search_Base DAF_Search_common <|-- DAS_UI DAF_Search_common <|-- DAF_Search_Base DAF_Search_common <|-- DAF_Search_Routing @enduml This UML file is the processed by PlantUML

Git bits 2

·204 words·1 min
Using the Scala source repo to demonstrate - see Github Show merged and unmerged branches # This command allows you to show all local branches merged / unmerged to current branch ➜ scala git:(2.12.x) git branch -a --merged * 2.12.x remotes/origin/2.11.x remotes/origin/2.12.x remotes/origin/HEAD -> origin/2.12.x ➜ scala git:(2.12.x) git branch -a --no-merged remotes/origin/2.10.x remotes/origin/2.8.x remotes/origin/2.9.x remotes/origin/DarkDimius-patch-1 remotes/origin/gh-pages remotes/origin/legacy/msil This shows you all local branches merged into named branch:

Git - find unmerged commits

·1000 words·5 mins
This is Ruby script I found way back and was using it since. The credits for creation goes to Zach Dennis. The script is decribed in his blog post The source is here Example # This is beginning of very long output from Groovy source The code # #!/usr/bin/env ruby require 'rubygems' gem 'term-ansicolor', '>=1.0.5' require 'term/ansicolor' class GitCommit attr_reader :content def initialize(content) @content = content end def sha @content.split[1] end def to_s `git log --pretty=format:"%h %ad %an - %s" #{sha}~1..#{sha}` end def unmerged? content =~ /^\+/ end def equivalent? content =~ /^\-/ end end class GitBranch attr_reader :name, :commits def initialize(name, commits) @name = name @commits = commits end # Returns origin from origin/some/branch/here def repository name.split("/", 2).first end # Returns some/branch/here from origin/some/branch/here def branch_name name.split("/", 2).last end def unmerged_commits commits.select{ |commit| commit.unmerged? } end def equivalent_commits commits.select{ |commit| commit.equivalent? } end end class GitBranches < Array def self.clean_branch_output(str) str.split(/\n/).map{ |e| e.strip.gsub(/\*\s+/, '') }.reject{ |branch| branch =~ /\b#{Regexp.escape(UPSTREAM)}\b/ }.sort end def self.local_branches clean_branch_output `git branch` end def self.remote_branches clean_branch_output `git branch -r` end def self.load(options) git_branches = new branches = if options[:local] local_branches elsif options[:remote] remote_branches end branches.each do |branch| raw_commits = `git cherry -v #{UPSTREAM} #{branch}`.split(/\n/).map{ |c| GitCommit.new(c) } git_branches << GitBranch.new(branch, raw_commits) end git_branches end def unmerged reject{ |branch| branch.commits.empty? }.sort_by{ |branch| branch.name } end def any_missing_commits? select{ |branch| branch.commits.any? }.any? end end class GitUnmerged VERSION = "1.1" include Term::ANSIColor attr_reader :branches def initialize(args) @options = {} @branches_to_prune = [] extract_options_from_args(args) end def load @branches ||= GitBranches.load(:local => local?, :remote => remote?) @branches.reject!{|b| @options[:exclude].include?(b.name)} if @options[:exclude].is_a?(Array) @branches.select!{|b| @options[:only].include?(b.name)} if @options[:only].is_a?(Array) end def print_overview load if @options[:exclude] && @options[:exclude].length > 0 puts "The following branches have been excluded" @options[:exclude].each do |branch_name| puts " #{branch_name}" end puts end if @options[:only] && @options[:only].length > 0 puts "The following branches will be compared against:" @options[:only].each do |branch_name| puts " #{branch_name}" end puts end if branches.any_missing_commits? puts "The following branches possibly have commits not merged to #{upstream}:" branches.each do |branch| num_unmerged = yellow(branch.unmerged_commits.size.to_s) num_equivalent = green(branch.equivalent_commits.size.to_s) puts %| #{branch.name} (#{num_unmerged}/#{num_equivalent} commits)| end end end def print_help puts <<-EOT.gsub(/^\s+\|/, '') |Usage: #{$0} [-a] [--upstream <branch>] [--remote] [--prune] | |This script wraps the "git cherry" command. It reports the commits from all local |branches which have not been merged into an upstream branch. | | #{yellow("yellow")} commits have not been merged | #{green("green")} commits have equivalent changes in <upstream> but different SHAs | |The default upstream is 'master' (or 'origin/master' if running with --remote) | |OPTIONS: | -a display all unmerged commits (verbose) | --remote (-r) compare remote branches instead of local branches | --upstream <branch> specify a specific upstream branch (defaults to master) | --exclude <branch>[,<branch>,...] specify a comma-separated list of branches to exclude | --only <branch>[,<branch>,...] specify a comma-separated list of branches to include | --prune prompts user to delete branches which have no differences with the upstream | |EXAMPLE: check for all unmerged commits | #{$0} | |EXAMPLE: check for all unmerged commits and merged commits (but with a different SHA) | #{$0} -a | |EXAMPLE: use a different upstream than master | #{$0} --upstream otherbranch | |EXAMPLE: compare remote branches against origin/master | #{$0} --remote (-r) | |EXAMPLE: delete branches without unmerged commits | #{$0} --prune | |EXAMPLE: delete remote branches without unmerged commits | #{$0} --remote --prune | |GITCONFIG: | If you name this file git-unmerged and place it somewhere in your PATH | you will be able to type "git unmerged" to use it. If you'd like to name | it something else and still refer to it with "git unmerged" then you'll | need to set up an alias: | git config --global alias.unmerged \\!#{$0} | |Version: #{VERSION} |Author: Zach Dennis <zdennis@mutuallyhuman.com> EOT exit end def print_version puts "#{VERSION}" end def branch_description local? ? "local" : "remote" end def print_specifics load if branches.any_missing_commits? print_breakdown else puts "There are no #{branch_description} branches out of sync with #{upstream}" end end def print_breakdown puts "Below is a breakdown for each branch. Here's a legend:" puts print_legend branches.each do |branch| puts print "#{branch.name}:" if branch.unmerged_commits.empty? && !show_equivalent_commits? print "(no unmerged commits" if prune? print ",", red(" this will be pruned") @branches_to_prune << branch end print ")\n" else puts end branch.unmerged_commits.each { |commit| puts yellow(commit.to_s) } if show_equivalent_commits? branch.equivalent_commits.each do |commit| puts green(commit.to_s) end end end end def print_legend load puts " " + yellow("yellow") + " commits have not been merged" puts " " + green("green") + " commits have equivalent changes in #{UPSTREAM} but different SHAs" if show_equivalent_commits? end def prune return unless prune? if @branches_to_prune.empty? puts "", "There are no branches to prune." else # Protects Heroku repo's rejected_master_branches = @branches_to_prune.reject!{|branch| branch.branch_name =~ /master/} puts "", "Are you sure you want to prune the following #{@branches_to_prune.size} branches?", "" puts red("(Keep in mind this will remove these branches from the remote repository)") if @remote @branches_to_prune.each do |branch| puts red(" #{branch.name}") end puts "(omitting branches named master)" if rejected_master_branches puts print "y or n: " if STDIN.gets=~/y/i @branches_to_prune.each do |branch| if local? `git branch -D #{branch.name}` elsif remote? puts "pruning: #{branch.branch_name} with 'git push #{branch.repository} :#{branch.branch_name}'" `git push #{branch.repository} :#{branch.branch_name}` end end puts "", "Pruned #{@branches_to_prune.size} branches." else puts "", "Pruning aborted. All branches were left unharmed." end end end def prune? ; @options[:prune ] ; end def show_help? ; @options[:show_help] ; end def show_equivalent_commits? ; @options[:show_equivalent_commits] ; end def show_version? ; @options[:show_version] ; end def upstream if @options[:upstream] @options[:upstream] elsif local? "master" elsif remote? "origin/master" end end private def extract_options_from_args(args) if args.include?("--remote") || args.include?("-r") @options[:remote] = true else @options[:local] = true end @options[:prune] = true if args.include?("--prune") @options[:show_help] = true if args.include?("-h") || args.include?("--help") @options[:show_equivalent_commits] = true if args.include?("-a") @options[:show_version] = true if args.include?("-v") || args.include?("--version") if index=args.index("--upstream") @options[:upstream] = args[index+1] end if index=args.index("--exclude") @options[:exclude] = args[index+1].split(',') end if index=args.index("--only") @options[:only] = args[index+1].split(',') end end def local? ; @options[:local] ; end def remote? ; @options[:remote] ; end end unmerged = GitUnmerged.new ARGV UPSTREAM = unmerged.upstream if unmerged.show_help? unmerged.print_help exit elsif unmerged.show_version? unmerged.print_version exit else unmerged.print_overview puts unmerged.print_specifics unmerged.prune end

Git committer activity

·672 words·4 mins
Git command git shortlog is very handy to see what is team activity. Show committer activity - whole project # (output shortened to first 20 lines) git shortlog -sn | head -20 2991 Paul King 1757 Cedric Champeau 1615 Jochen Theodorou 1031 James Strachan 749 Guillaume Laforge 312 Roshan Dawrani 306 Jason Dillon 301 Danno Ferrin 284 Alex Tkachman 273 PascalSchumacher 230 John Wilson 217 Pascal Schumacher 204 pascalschumacher 160 Thibault Kruse 158 Jeremy Rayner 134 Russel Winder 123 Cédric Champeau 122 Hamlet D'Arcy 116 Dierk Koenig 104 Pilho Kim variant (without n) has different ordering:

Git project statistic tool

·426 words·3 mins
Git Inspector # Python based, requires Python 2.6+ Works OOTB on Mac Installation # Download TAR from https://code.google.com/p/gitinspector/ unzipped to /opt/gitinspector-0.3.2: total 52K -rw-r--r-- 1 miro 999 Jul 29 2013 DESCRIPTION.txt -rw-r--r-- 1 miro 32K Jun 14 2013 LICENSE.txt -rw-r--r-- 1 miro 78 Jul 2 2013 MANIFEST.in -rw-r--r-- 1 miro 681 Jan 13 2014 README.txt drwxr-xr-x 45 miro 1.5K Mar 20 16:06 gitinspector -rw-r--r-- 1 miro 1.9K Jan 14 2014 setup.py -rw-r--r-- 1 miro 110 Jul 27 2013 stdeb.cfg create symlink to it from ~/bin (is on path) ln -s /opt/gitinspector-0.3.2/gitinspector/gitinspector.py ~/bin/gitinspector.py ➜ ~ ll ~/bin | grep gitin lrwxr-xr-x 1 miro 52 Mar 20 16:06 gitinspector.py -> /opt/gitinspector-0.3.2/gitinspector/gitinspector.py Example # ➜ gitinspector git:(master) ~/bin/gitinspector.py -Tlr --since=2014-01-01 --until=2015-05-05 Statistical information for the repository 'gitinspector' was gathered on 2019/11/27. The following historical commit information, by author, was found in the repository: Author Commits Insertions Deletions % of changes Adam Waldenberg 41 569 249 95.34 Chris Barry 1 3 3 0.70 Christian Kastner 2 9 5 1.63 Diomidis Spinellis 2 3 3 0.70 Dmitry Dzhus 1 3 3 0.70 Jon Warghed 1 1 0 0.12 Yannick Moy 1 4 3 0.82 Below are the number of rows from each author that have survived and are still intact in the current revision: Author Rows Stability Age % in comments Adam Waldenberg 468 82.2 8.7 6.84 Chris Barry 3 100.0 4.5 0.00 Christian Kastner 8 88.9 3.3 0.00 Diomidis Spinellis 1 33.3 4.0 100.00 Dmitry Dzhus 3 100.0 2.6 0.00 Jon Warghed 1 100.0 3.2 0.00 Yannick Moy 3 75.0 3.7 0.00 The following history timeline has been gathered from the repository: Author 2014-01 2014-02 2014-03 2014-11 2014-12 2015-02 Adam Waldenberg -+++++++ --++++++ ---+++++ ----+++++ --+++++++ -+++++++ Chris Barry . Christian Kastner . Diomidis Spinellis . Dmitry Dzhus . Jon Warghed . Yannick Moy . Modified Rows: 170 387 7 223 64 7 The following responsibilities, by author, were found in the current revision of the repository (comments are excluded from the line count, if possible): Adam Waldenberg is mostly responsible for: 128 gitinspector/metrics.py 97 gitinspector/blame.py 30 gitinspector/localization.py 29 gitinspector/clone.py 26 gitinspector/terminal.py 26 gitinspector/basedir.py 19 gitinspector/changes.py 17 gitinspector/filtering.py 16 gitinspector/format.py 15 gitinspector/gitinspector.py Chris Barry is mostly responsible for: 2 gitinspector/format.py 1 gitinspector/gravatar.py Christian Kastner is mostly responsible for: 5 gitinspector/basedir.py 3 gitinspector/format.py Dmitry Dzhus is mostly responsible for: 3 gitinspector/comment.py Jon Warghed is mostly responsible for: 1 gitinspector/changes.py Yannick Moy is mostly responsible for: 3 gitinspector/comment.py The extensions below were found in the repository history (extensions used during statistical analysis are marked): 1 css header html po pot [py] txt

Finding unmerged commits in all branches

·669 words·4 mins
This one goes beyond git, but is very useful. Ruby script that produces this: Here is the script #!/usr/bin/env ruby require 'rubygems' gem 'term-ansicolor', '=1.3.0' require 'term/ansicolor' class GitCommit attr_reader :content def initialize(content) @content = content end def sha @content.split[1] end def to_s `git log --pretty=format:"%h %ad %an - %s" #{sha}~1..#{sha}` end def unmerged? content =~ /^\+/ end def equivalent? content =~ /^\-/ end end class GitBranch attr_reader :name, :commits def initialize(name, commits) @name = name @commits = commits end def unmerged_commits commits.select{ |commit| commit.unmerged? } end def equivalent_commits commits.select{ |commit| commit.equivalent? } end end class GitBranches < Array def self.clean_branch_output(str) str.split(/\n/).map{ |e| e.strip.gsub(/\*\s+/, '') }.reject{ |branch| branch =~ /\b#{Regexp.escape(UPSTREAM)}\b/ }.sort end def self.local_branches clean_branch_output `git branch` end def self.remote_branches clean_branch_output `git branch -r` end def self.load(options) git_branches = new branches = if options[:local] local_branches elsif options[:remote] remote_branches end branches.each do |branch| raw_commits = `git cherry -v #{UPSTREAM} #{branch}`.split(/\n/).map{ |c| GitCommit.new(c) } git_branches << GitBranch.new(branch, raw_commits) end git_branches end def unmerged reject{ |branch| branch.commits.empty? }.sort_by{ |branch| branch.name } end def any_missing_commits? select{ |branch| branch.commits.any? }.any? end end class GitUnmerged VERSION = "1.0.1" include Term::ANSIColor attr_reader :branches def initialize(args) @options = {} extract_options_from_args(args) end def load @branches ||= GitBranches.load(:local => local?, :remote => remote?) end def print_overview load if branches.any_missing_commits? puts "The following branches possibly have commits not merged to #{upstream}:" branches.each do |branch| num_unmerged = yellow(branch.unmerged_commits.size.to_s) num_equivalent = green(branch.equivalent_commits.size.to_s) puts %| #{branch.name} (#{num_unmerged}/#{num_equivalent} commits)| end end end def print_help puts <<-EOT.gsub(/^\s+\|/, '') |Usage: #{$0} [-a] [--upstream <branch>] [--remote] | |This script wraps the "git cherry" command. It reports the commits from all local |branches which have not been merged into an upstream branch. | | #{yellow("yellow")} commits have not been merged | #{green("green")} commits have equivalent changes in <upstream> but different SHAs | |The default upstream is 'master'. | |OPTIONS: | -a display all unmerged commits (verbose) | --remote compare remote branches instead of local branches | --upstream <branch> specify a specific upstream branch | |EXAMPLE: check for all unmerged commits | #{$0} | |EXAMPLE: check for all unmerged commits and merged commits (but with a different SHA) | #{$0} -a | |EXAMPLE: use a different upstream than master | #{$0} --upstream otherbranch | |EXAMPLE: compare remote branches against origin/master | #{$0} --remote | |GITCONFIG: | If you name this file git-unmerged and place it somewhere in your PATH | you will be able to type "git unmerged" to use it. If you'd like to name | it something else and still refer to it with "git unmerged" then you'll | need to set up an alias: | git config --global alias.unmerged \\!#{$0} | |Version: #{VERSION} |Author: Zach Dennis <zdennis@mutuallyhuman.com> EOT exit end def print_version puts "#{VERSION}" end def branch_description local? ? "local" : "remote" end def print_specifics load if branches.any_missing_commits? print_breakdown else puts "There are no #{branch_description} branches out of sync with #{upstream}" end end def print_breakdown puts "Below is a breakdown for each branch. Here's a legend:" puts print_legend branches.each do |branch| puts print "#{branch.name}:" if branch.unmerged_commits.empty? && !show_equivalent_commits? print "(no umerged commits, must have merged commits with different SHAs)\n" else puts end branch.unmerged_commits.each { |commit| puts yellow(commit.to_s) } if show_equivalent_commits? branch.equivalent_commits.each do |commit| puts green(commit.to_s) end end end end def print_legend load puts " " + yellow("yellow") + " commits have not been merged" puts " " + green("green") + " commits have equivalent changes in #{UPSTREAM} but different SHAs" if show_equivalent_commits? end def show_help? ; @options[:show_help] ; end def show_equivalent_commits? ; @options[:show_equivalent_commits] ; end def show_version? ; @options[:show_version] ; end def upstream if @options[:upstream] @options[:upstream] elsif local? "master" elsif remote? "origin/master" end end private def extract_options_from_args(args) if args.include?("--remote") @options[:remote] = true else @options[:local] = true end @options[:show_help] = true if args.include?("-h") || args.include?("--help") @options[:show_equivalent_commits] = true if args.include?("-a") @options[:show_version] = true if args.include?("-v") || args.include?("--version") if index=args.index("--upstream") @options[:upstream] = args[index+1] end end def local? ; @options[:local] ; end def remote? ; @options[:remote] ; end end unmerged = GitUnmerged.new ARGV UPSTREAM = unmerged.upstream if unmerged.show_help? unmerged.print_help exit elsif unmerged.show_version? unmerged.print_version exit else unmerged.print_overview puts unmerged.print_specifics end