diff --git a/docs/_modules/githelper.html b/docs/_modules/githelper.html index 86fd658..ce21472 100644 --- a/docs/_modules/githelper.html +++ b/docs/_modules/githelper.html @@ -137,15 +137,13 @@

Source code for githelper

 
     $ gh b
     branch
-    </Users/liyanage/Projects/foo>                               0↑ 0↓ master      4c3b6721
-    </Users/liyanage/Projects/foo/repositories/LibraryManager>   0↑ 0↓ master      301105f7
-    </Users/liyanage/Projects/foo/repositories/Reports *>        0↑ 0↓ master      7ffa7408
-    </Users/liyanage/Projects/foo/repositories/analyzer>         0↑ 0↓ feature/xyz c2881596
-    </Users/liyanage/Projects/foo/repositories/common l>         0↑ 0↓ master      f0a1ec75
+    </Users/liyanage/Projects/foo>                               0↑ 0↓ master      4c3b6721  1h
+    </Users/liyanage/Projects/foo/repositories/LibraryManager>   0↑ 0↓ master      301105f7  1h
+    </Users/liyanage/Projects/foo/repositories/Reports *>        0↑ 0↓ master      7ffa7408  2h
+    </Users/liyanage/Projects/foo/repositories/analyzer>         0↑ 0↓ feature/xyz c2881596  5h
+    </Users/liyanage/Projects/foo/repositories/common l>         0↑ 0↓ master      f0a1ec75 34m
 
-In column order, it lists the path, commits to push, commits to pull, branch name, current commit.
-You need to run the ``fetch`` subcommand first for the commits to pull/push information to be
-up to date.
+See the subcommand's detailed help for an explanation of the columns.
 
 Many subcommands, ``fetch`` included, run the ``branch`` subcommand automatically after they finish.
 
@@ -251,6 +249,7 @@ 

Source code for githelper

 import logging
 import getpass
 import tempfile
+import datetime
 import argparse
 import textwrap
 import StringIO
@@ -568,6 +567,27 @@ 

Source code for githelper

     def head_commit_hash(self):
         return self.output_for_git_command(['git', 'rev-parse', 'HEAD'])[0][:8]
 
+    def head_commit_age(self):
+        head_commit_timestamp = self.output_for_git_command(['git', 'show', '--format=%cI', '--no-patch', 'HEAD'])[0][:19]
+        return datetime.datetime.now() - datetime.datetime.strptime(head_commit_timestamp, "%Y-%m-%dT%H:%M:%S")
+
+    def head_commit_age_approximate_string(self):
+        seconds = self.head_commit_age().total_seconds()
+
+        days = int(seconds / (60 * 60 * 24))
+        if days:
+            return '{}d'.format(days)
+
+        hours = int(seconds / (60 * 60))
+        if hours:
+            return '{}h'.format(hours)
+        
+        minutes = int(seconds / 60)
+        if minutes:
+            return '{}m'.format(minutes)
+        
+        return '{}s'.format(int(seconds))
+
 
[docs] def current_repository(self): """Returns the name of the current git repository.""" output = self.output_for_git_command('git remote -v'.split())[0] @@ -1309,6 +1329,7 @@

Source code for githelper

         (string.rjust, lambda x: unicode(len(x.commits_only_in_upstream())) + u'↓' if x.current_branch_has_upstream() else '-'),
         (string.ljust, lambda x: x.current_branch()),
         (string.ljust, lambda x: x.head_commit_hash()),
+        (string.rjust, lambda x: str(x.head_commit_age_approximate_string())),
     )
     
     def column_count(self):
@@ -1340,13 +1361,19 @@ 

Source code for githelper

 
                 $ gh b
                 branch
-                </Users/liyanage/Projects/foo>                               0↑ 0↓ master      4c3b6721
-                </Users/liyanage/Projects/foo/repositories/LibraryManager>   0↑ 0↓ master      301105f7
-                </Users/liyanage/Projects/foo/repositories/Reports *>        0↑ 0↓ master      7ffa7408
-                </Users/liyanage/Projects/foo/repositories/analyzer>         0↑ 0↓ feature/xyz c2881596
-                </Users/liyanage/Projects/foo/repositories/common l>         0↑ 0↓ master      f0a1ec75
-
-            In column order, it lists the path, commits to push, commits to pull, branch name, current commit.
+                </Users/liyanage/Projects/foo>                               0↑ 0↓ master      4c3b6721  1h
+                </Users/liyanage/Projects/foo/repositories/LibraryManager>   0↑ 0↓ master      301105f7  1h
+                </Users/liyanage/Projects/foo/repositories/Reports *>        0↑ 0↓ master      7ffa7408  2h
+                </Users/liyanage/Projects/foo/repositories/analyzer>         0↑ 0↓ feature/xyz c2881596  5h
+                </Users/liyanage/Projects/foo/repositories/common l>         0↑ 0↓ master      f0a1ec75 34m
+
+            In column order, it lists:
+            - the path to the working copy
+            - the number of commits to push
+            - the number of commits to pull
+            - the branch name
+            - the head commit ID
+            - the age of the head commit
             
             For the "commits to pull" information to be up to date, you have to run the "fetch" subcommand first.
             
diff --git a/docs/index.html b/docs/index.html
index ef6d2e3..977b22d 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -119,16 +119,14 @@ 

Command Line Utility Examples
$ gh b
 branch
-</Users/liyanage/Projects/foo>                               0↑ 0↓ master      4c3b6721
-</Users/liyanage/Projects/foo/repositories/LibraryManager>   0↑ 0↓ master      301105f7
-</Users/liyanage/Projects/foo/repositories/Reports *>        0↑ 0↓ master      7ffa7408
-</Users/liyanage/Projects/foo/repositories/analyzer>         0↑ 0↓ feature/xyz c2881596
-</Users/liyanage/Projects/foo/repositories/common l>         0↑ 0↓ master      f0a1ec75
+</Users/liyanage/Projects/foo>                               0↑ 0↓ master      4c3b6721  1h
+</Users/liyanage/Projects/foo/repositories/LibraryManager>   0↑ 0↓ master      301105f7  1h
+</Users/liyanage/Projects/foo/repositories/Reports *>        0↑ 0↓ master      7ffa7408  2h
+</Users/liyanage/Projects/foo/repositories/analyzer>         0↑ 0↓ feature/xyz c2881596  5h
+</Users/liyanage/Projects/foo/repositories/common l>         0↑ 0↓ master      f0a1ec75 34m
 

-

In column order, it lists the path, commits to push, commits to pull, branch name, current commit. -You need to run the fetch subcommand first for the commits to pull/push information to be -up to date.

+

See the subcommand’s detailed help for an explanation of the columns.

Many subcommands, fetch included, run the branch subcommand automatically after they finish.

These are just a few examples, see the command line help for the remaining subcommands.

diff --git a/docs/searchindex.js b/docs/searchindex.js index 4a7ffcc..c0887b3 100644 --- a/docs/searchindex.js +++ b/docs/searchindex.js @@ -1 +1 @@ -Search.setIndex({envversion:42,terms:{all:0,code:0,prefix:0,subclass:0,follow:0,depend:0,remote_branch_nam:0,branch_nam:0,sourc:0,string:0,fals:0,subcommand:0,candid:0,upstream:0,"301105f7":0,tri:0,level:0,list:0,iter:0,stderr:0,past:0,zero:0,pass:0,further:0,has_branch:0,index:0,what:0,abc:0,sub:0,configure_argument_pars:0,anywai:0,current:0,abbrevi:0,version:0,method:0,full:0,deriv:0,here:0,create_stash_and_reset_hard:0,modif:0,switched_to_branch:0,path:0,modifi:0,implicit:0,valu:0,is_root:0,great:0,echo_stdout:0,popen:0,action:0,chang:0,echo_stderr:0,substr:0,txt:0,list_dirti:0,from:0,would:0,commun:0,two:0,next:0,few:0,call:0,usr:0,type:0,sudo:0,trail:0,flag:0,chdir_to_path:0,must:0,none:0,retriev:0,restor:0,alia:0,prepar:0,work:0,remain:0,can:0,store_stderr:0,root:0,fetch:0,def:0,overrid:0,current_branch:0,give:0,process:0,dirty_file_lin:0,add_argu:0,want:0,end:0,newlin:0,anoth:0,write:0,env:0,instead:0,ancestor:0,process_working_copi:0,updat:0,some_st:0,after:0,befor:0,date:0,data:0,stderr_rul:0,github:0,classmethod:0,stash:0,element:0,perform:0,"switch":0,store_stdout:0,combin:0,allow:0,exclus:0,order:0,origin:0,help:0,over:0,becaus:0,through:0,paramet:0,local_branch_nam:0,liyanag:0,main:0,non:0,independ:0,"return":0,thei:0,python:0,dat:0,front:0,subproject:0,somewher:0,name:0,anyth:0,stop_travers:0,each:0,bufsiz:0,individu:0,hard:0,commits_only_in_upstream:0,expect:0,out:0,shown:0,contigu:0,rev:0,stdout_rul:0,print:0,githelper_loc:0,ref:0,insid:0,root_working_copi:0,argv:0,base:0,afterward:0,could:0,filter:0,turn:0,"4c3b6721":0,first:0,oper:0,wants_working_copi:0,directli:0,onc:0,arrai:0,subrepositori:0,yourself:0,given:0,script:0,system:0,wrapper:0,master:0,statement:0,termin:0,conveni:0,store:0,shell:0,consol:0,option:0,namespac:0,tool:0,copi:0,part:0,mostli:0,exactli:0,target:0,provid:0,remov:0,tree:0,second:0,charact:0,project:0,reus:0,str:0,were:0,argument:0,raw:0,have:0,need:0,prepare_for_root:0,inform:0,self:0,sandbox:0,also:0,maintain:0,take:0,which:0,begin:0,track:0,some_subcommand:0,object:0,most:0,regular:0,renam:0,doc:0,later:0,cover:0,doe:0,pipe:0,clean:0,usual:0,subprocess:0,find:0,gitworkingcopi:0,onli:0,execut:0,explain:0,configur:0,c2881596:0,analyz:0,"__call__":0,local:0,popenoutputfilt:0,variou:0,get:0,express:0,stop:0,report:0,sta:0,bar:0,baz:0,remot:0,common:0,contain:0,where:0,view:0,set:0,see:0,temporarili:0,mandatori:0,arg:0,root_wc:0,statu:0,someth:0,state:0,"import":0,parent:0,filteringpopen:0,extens:0,entir:0,addit:0,both:0,last:0,against:0,etc:0,instanc:0,context:0,let:0,com:0,comment:0,kwd:0,point:0,instanti:0,overview:0,argumentpars:0,chmod:0,except:0,header:0,suppli:0,assum:0,evalu:0,empti:0,mark:0,interest:0,abstractsubcommand:0,search:0,ani:0,look:0,defin:0,invok:0,abov:0,anchor:0,argpars:0,stdout:0,demo:0,stdoutlin:0,them:0,kwarg:0,"__init__":0,around:0,output_for_git_command:0,receiv:0,shorten:0,stderrlin:0,html:0,complet:0,finish:0,http:0,nest:0,rais:0,user:0,mani:0,implement:0,travers:0,task:0,entri:0,without:0,thi:0,everyth:0,unchang:0,identifi:0,just:0,rest:0,yet:0,returncod:0,shortcut:0,add:0,exercis:0,els:0,check_returncod:0,match:0,bin:0,subextern:0,"7ffa7408":0,dirti:0,recurs:0,like:0,remind:0,either:0,output:0,unanbigu:0,manag:0,captur:0,some:0,hard_reset_current_branch:0,librari:0,lead:0,per:0,buffer:0,exit:0,foo:0,refer:0,run:0,commits_not_in_upstream:0,uncommit:0,step:0,repositori:0,actual:0,column:0,switch_to_branch:0,page:0,constructor:0,commit:0,produc:0,is_dirti:0,own:0,xyz:0,automat:0,been:0,your:0,inclus:0,git:0,remote_branch_name_for_name_list:0,wai:0,support:0,custom:0,avail:0,start:0,interfac:0,includ:0,forward:0,parse_arg:0,"function":0,form:0,don:0,"true":0,reset:0,pull:0,subcommandfoo:0,callabl:0,possibl:0,"default":0,checkout:0,below:0,current_repositori:0,otherwis:0,similar:0,featur:0,creat:0,"int":0,certain:0,parser:0,repres:0,file:0,curl:0,check:0,chained_post_traversal_subcommand_for_root_working_copi:0,detail:0,bool:0,branch:0,you:0,run_shell_command:0,f0a1ec75:0,filter_rul:0,sequenc:0,name_list:0,librarymanag:0,self_or_descendants_dirty_working_copi:0,directori:0,descript:0,"__iter__":0,rule:0,potenti:0,time:0,push:0},objtypes:{"0":"py:module","1":"py:method","2":"py:classmethod","3":"py:class","4":"py:attribute"},objnames:{"0":["py","module","Python module"],"1":["py","method","Python method"],"2":["py","classmethod","Python class method"],"3":["py","class","Python class"],"4":["py","attribute","Python attribute"]},filenames:["index"],titles:["Welcome to githelper’s documentation!"],objects:{"":{githelper:[0,0,0,"-"]},"githelper.GitWorkingCopy":{traverse:[0,1,1,""],current_branch:[0,1,1,""],hard_reset_current_branch:[0,1,1,""],is_dirty:[0,1,1,""],dirty_file_lines:[0,1,1,""],run_shell_command:[0,1,1,""],ancestors:[0,1,1,""],remote_branch_name_for_name_list:[0,1,1,""],output_for_git_command:[0,1,1,""],switch_to_branch:[0,1,1,""],remote_branch_names:[0,1,1,""],root_working_copy:[0,1,1,""],local_branch_names:[0,1,1,""],commits_not_in_upstream:[0,1,1,""],switched_to_branch:[0,1,1,""],is_root:[0,1,1,""],"__iter__":[0,1,1,""],create_stash_and_reset_hard:[0,1,1,""],chdir_to_path:[0,1,1,""],self_or_descendants_dirty_working_copies:[0,1,1,""],STOP_TRAVERSAL:[0,4,1,""],commits_only_in_upstream:[0,1,1,""],current_repository:[0,1,1,""],has_branch:[0,1,1,""],branch_names:[0,1,1,""]},"githelper.FilteringPopen":{stdoutlines:[0,1,1,""],stderrlines:[0,1,1,""],returncode:[0,1,1,""],run:[0,1,1,""]},"githelper.AbstractSubcommand":{"__call__":[0,1,1,""],configure_argument_parser:[0,2,1,""],prepare_for_root:[0,1,1,""],chained_post_traversal_subcommand_for_root_working_copy:[0,1,1,""],wants_working_copy:[0,2,1,""]},githelper:{GitWorkingCopy:[0,3,1,""],FilteringPopen:[0,3,1,""],PopenOutputFilter:[0,3,1,""],AbstractSubcommand:[0,3,1,""]}},titleterms:{plug:0,extend:0,welcom:0,githelp:0,api:0,modul:0,usag:0,toolkit:0,indic:0,util:0,exampl:0,command:0,tabl:0,instal:0,line:0,document:0,"class":0,introduct:0}}) \ No newline at end of file +Search.setIndex({envversion:42,terms:{all:0,code:0,prefix:0,per:0,follow:0,depend:0,branch_nam:0,sourc:0,string:0,fals:0,subcommand:0,candid:0,upstream:0,"301105f7":0,tri:0,level:0,"34m":0,list:0,iter:0,stderr:0,past:0,zero:0,pass:0,further:0,has_branch:0,index:0,what:0,abc:0,sub:0,configure_argument_pars:0,find:0,gitworkingcopi:0,abbrevi:0,version:0,method:0,full:0,deriv:0,here:0,create_stash_and_reset_hard:0,modif:0,argv:0,path:0,modifi:0,implicit:0,valu:0,great:0,echo_stdout:0,popen:0,action:0,chang:0,echo_stderr:0,substr:0,txt:0,list_dirti:0,from:0,would:0,commun:0,two:0,next:0,few:0,call:0,usr:0,type:0,sudo:0,trail:0,flag:0,chdir_to_path:0,must:0,none:0,retriev:0,restor:0,alia:0,prepar:0,work:0,remain:0,can:0,store_stderr:0,root:0,fetch:0,def:0,overrid:0,current_branch:0,give:0,process:0,dirty_file_lin:0,add_argu:0,want:0,end:0,newlin:0,anoth:0,write:0,env:0,instead:0,subproject:0,process_working_copi:0,updat:0,some_st:0,after:0,befor:0,buffer:0,date:[],data:0,stderr_rul:0,github:0,classmethod:0,stash:0,element:0,perform:0,sandbox:0,maintain:0,combin:0,allow:0,exclus:0,order:[],origin:0,help:0,over:0,becaus:0,through:0,paramet:0,local_branch_nam:0,liyanag:0,main:0,non:0,subrepositori:0,"return":0,thei:0,python:0,dat:0,front:0,ancestor:0,somewher:0,name:0,anyth:0,stop_travers:0,each:0,individu:0,hard:0,commits_only_in_upstream:0,been:0,expect:0,out:0,shown:0,contigu:0,rev:0,stdout_rul:0,print:0,githelper_loc:0,ref:0,store_stdout:0,insid:0,root_working_copi:0,switched_to_branch:0,base:0,afterward:0,could:0,filter:0,turn:0,"4c3b6721":0,first:0,oper:0,wants_working_copi:0,directli:0,onc:0,arrai:0,independ:0,yourself:0,given:0,script:0,system:0,wrapper:0,master:0,statement:0,termin:0,conveni:0,store:0,shell:0,consol:0,option:0,namespac:0,tool:0,copi:0,part:0,mostli:0,exactli:0,sta:0,remot:0,remov:0,tree:0,second:0,charact:0,project:0,reus:0,str:0,were:0,argument:0,raw:0,have:0,need:0,prepare_for_root:0,inform:[],self:0,"switch":0,also:0,take:0,which:0,begin:0,track:0,some_subcommand:0,object:0,most:0,regular:0,renam:0,doc:0,later:0,cover:0,doe:0,pipe:0,clean:0,usual:0,subprocess:0,anywai:0,current:0,onli:0,just:0,explain:0,configur:0,c2881596:0,analyz:0,"__call__":0,local:0,popenoutputfilt:0,variou:0,get:0,express:0,stop:0,report:0,target:0,bar:0,baz:0,uncommit:0,provid:0,common:0,contain:0,where:0,view:0,set:0,see:0,temporarili:0,mandatori:0,arg:0,statu:0,someth:0,state:0,"import":0,parent:0,filteringpopen:0,extens:0,entir:0,addit:0,both:0,last:0,against:0,etc:0,instanc:0,context:0,let:0,com:0,comment:0,kwd:0,point:0,instanti:0,overview:0,argumentpars:0,chmod:0,except:0,header:0,suppli:0,assum:0,creat:0,empti:0,mark:0,interest:0,abstractsubcommand:0,search:0,ani:0,look:0,defin:0,invok:0,abov:0,anchor:0,argpars:0,stdout:0,demo:0,stdoutlin:0,them:0,kwarg:0,"__init__":0,around:0,output_for_git_command:0,receiv:0,shorten:0,stderrlin:0,html:0,complet:0,finish:0,http:0,nest:0,rais:0,user:0,mani:0,implement:0,travers:0,task:0,entri:0,without:0,thi:0,everyth:0,unchang:0,explan:0,identifi:0,execut:0,rest:0,yet:0,returncod:0,shortcut:0,add:0,exercis:0,els:0,check_returncod:0,match:0,bin:0,subextern:0,"7ffa7408":0,dirti:0,step:0,recurs:0,like:0,remind:0,either:0,output:0,unanbigu:0,manag:0,captur:0,some:0,hard_reset_current_branch:0,librari:0,lead:0,subclass:0,remote_branch_nam:0,exit:0,foo:0,refer:0,run:0,name_list:0,is_root:0,root_wc:0,repositori:0,actual:0,column:0,switch_to_branch:0,page:0,constructor:0,commit:0,produc:0,is_dirti:0,own:0,xyz:0,automat:0,bufsiz:0,your:0,inclus:0,git:0,remote_branch_name_for_name_list:0,wai:0,support:0,custom:0,avail:0,start:0,interfac:0,includ:0,forward:0,parse_arg:0,"function":0,form:0,don:0,"true":0,reset:0,pull:[],subcommandfoo:0,callabl:0,possibl:0,"default":0,checkout:0,below:0,current_repositori:0,otherwis:0,similar:0,featur:0,evalu:0,"int":0,certain:0,parser:0,repres:0,file:0,curl:0,check:0,chained_post_traversal_subcommand_for_root_working_copi:0,detail:0,bool:0,branch:0,you:0,run_shell_command:0,f0a1ec75:0,filter_rul:0,sequenc:0,commits_not_in_upstream:0,librarymanag:0,self_or_descendants_dirty_working_copi:0,directori:0,descript:0,"__iter__":0,rule:0,potenti:0,time:0,push:0},objtypes:{"0":"py:module","1":"py:method","2":"py:classmethod","3":"py:class","4":"py:attribute"},objnames:{"0":["py","module","Python module"],"1":["py","method","Python method"],"2":["py","classmethod","Python class method"],"3":["py","class","Python class"],"4":["py","attribute","Python attribute"]},filenames:["index"],titles:["Welcome to githelper’s documentation!"],objects:{"":{githelper:[0,0,0,"-"]},"githelper.GitWorkingCopy":{traverse:[0,1,1,""],current_branch:[0,1,1,""],hard_reset_current_branch:[0,1,1,""],is_dirty:[0,1,1,""],dirty_file_lines:[0,1,1,""],run_shell_command:[0,1,1,""],ancestors:[0,1,1,""],remote_branch_name_for_name_list:[0,1,1,""],output_for_git_command:[0,1,1,""],switch_to_branch:[0,1,1,""],remote_branch_names:[0,1,1,""],root_working_copy:[0,1,1,""],local_branch_names:[0,1,1,""],commits_not_in_upstream:[0,1,1,""],switched_to_branch:[0,1,1,""],is_root:[0,1,1,""],"__iter__":[0,1,1,""],create_stash_and_reset_hard:[0,1,1,""],chdir_to_path:[0,1,1,""],self_or_descendants_dirty_working_copies:[0,1,1,""],STOP_TRAVERSAL:[0,4,1,""],commits_only_in_upstream:[0,1,1,""],current_repository:[0,1,1,""],has_branch:[0,1,1,""],branch_names:[0,1,1,""]},"githelper.FilteringPopen":{stdoutlines:[0,1,1,""],stderrlines:[0,1,1,""],returncode:[0,1,1,""],run:[0,1,1,""]},"githelper.AbstractSubcommand":{"__call__":[0,1,1,""],configure_argument_parser:[0,2,1,""],prepare_for_root:[0,1,1,""],chained_post_traversal_subcommand_for_root_working_copy:[0,1,1,""],wants_working_copy:[0,2,1,""]},githelper:{GitWorkingCopy:[0,3,1,""],FilteringPopen:[0,3,1,""],PopenOutputFilter:[0,3,1,""],AbstractSubcommand:[0,3,1,""]}},titleterms:{plug:0,extend:0,welcom:0,githelp:0,modul:0,usag:0,toolkit:0,indic:0,exampl:0,util:0,api:0,command:0,tabl:0,instal:0,line:0,document:0,"class":0,introduct:0}}) \ No newline at end of file diff --git a/githelper/githelper.py b/githelper/githelper.py index aa7b895..112dad9 100755 --- a/githelper/githelper.py +++ b/githelper/githelper.py @@ -88,15 +88,13 @@ $ gh b branch - 0↑ 0↓ master 4c3b6721 - 0↑ 0↓ master 301105f7 - 0↑ 0↓ master 7ffa7408 - 0↑ 0↓ feature/xyz c2881596 - 0↑ 0↓ master f0a1ec75 + 0↑ 0↓ master 4c3b6721 1h + 0↑ 0↓ master 301105f7 1h + 0↑ 0↓ master 7ffa7408 2h + 0↑ 0↓ feature/xyz c2881596 5h + 0↑ 0↓ master f0a1ec75 34m -In column order, it lists the path, commits to push, commits to pull, branch name, current commit. -You need to run the ``fetch`` subcommand first for the commits to pull/push information to be -up to date. +See the subcommand's detailed help for an explanation of the columns. Many subcommands, ``fetch`` included, run the ``branch`` subcommand automatically after they finish. @@ -202,6 +200,7 @@ def configure_argument_parser(cls, parser): import logging import getpass import tempfile +import datetime import argparse import textwrap import StringIO @@ -519,6 +518,27 @@ def current_branch(self): def head_commit_hash(self): return self.output_for_git_command(['git', 'rev-parse', 'HEAD'])[0][:8] + def head_commit_age(self): + head_commit_timestamp = self.output_for_git_command(['git', 'show', '--format=%cI', '--no-patch', 'HEAD'])[0][:19] + return datetime.datetime.now() - datetime.datetime.strptime(head_commit_timestamp, "%Y-%m-%dT%H:%M:%S") + + def head_commit_age_approximate_string(self): + seconds = self.head_commit_age().total_seconds() + + days = int(seconds / (60 * 60 * 24)) + if days: + return '{}d'.format(days) + + hours = int(seconds / (60 * 60)) + if hours: + return '{}h'.format(hours) + + minutes = int(seconds / 60) + if minutes: + return '{}m'.format(minutes) + + return '{}s'.format(int(seconds)) + def current_repository(self): """Returns the name of the current git repository.""" output = self.output_for_git_command('git remote -v'.split())[0] @@ -1260,6 +1280,7 @@ class SubcommandBranch(AbstractSubcommand): (string.rjust, lambda x: unicode(len(x.commits_only_in_upstream())) + u'↓' if x.current_branch_has_upstream() else '-'), (string.ljust, lambda x: x.current_branch()), (string.ljust, lambda x: x.head_commit_hash()), + (string.rjust, lambda x: str(x.head_commit_age_approximate_string())), ) def column_count(self): @@ -1291,13 +1312,19 @@ def configure_argument_parser(cls, parser): $ gh b branch - 0↑ 0↓ master 4c3b6721 - 0↑ 0↓ master 301105f7 - 0↑ 0↓ master 7ffa7408 - 0↑ 0↓ feature/xyz c2881596 - 0↑ 0↓ master f0a1ec75 - - In column order, it lists the path, commits to push, commits to pull, branch name, current commit. + 0↑ 0↓ master 4c3b6721 1h + 0↑ 0↓ master 301105f7 1h + 0↑ 0↓ master 7ffa7408 2h + 0↑ 0↓ feature/xyz c2881596 5h + 0↑ 0↓ master f0a1ec75 34m + + In column order, it lists: + - the path to the working copy + - the number of commits to push + - the number of commits to pull + - the branch name + - the head commit ID + - the age of the head commit For the "commits to pull" information to be up to date, you have to run the "fetch" subcommand first.