gitstatus.py 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. #!/usr/bin/env python
  2. from __future__ import print_function
  3. import sys
  4. import re
  5. from subprocess import Popen, PIPE, check_output
  6. # `git status --porcelain --branch` can collect all information
  7. # branch, remote_branch, untracked, staged, changed, conflicts, ahead, behind
  8. po = Popen(['git', 'status', '--porcelain', '--branch'], stdout=PIPE, stderr=PIPE)
  9. stdout, sterr = po.communicate()
  10. if po.returncode != 0:
  11. sys.exit(0) # Not a git repository
  12. # collect git status information
  13. untracked, staged, changed, conflicts = [], [], [], []
  14. ahead, behind = 0, 0
  15. status = [(line[0], line[1], line[2:]) for line in stdout.decode('utf-8').splitlines()]
  16. for st in status:
  17. if st[0] == '#' and st[1] == '#':
  18. if re.search('Initial commit on', st[2]):
  19. branch = st[2].split(' ')[-1]
  20. elif re.search('no branch', st[2]):
  21. branch = check_output(['git', 'rev-parse', '--short', 'HEAD']).decode('utf-8').strip()
  22. elif len(st[2].strip().split('...')) == 1:
  23. branch = st[2].strip()
  24. else:
  25. # current and remote branch info
  26. branch, rest = st[2].strip().split('...')
  27. if len(rest.split(' ')) == 1:
  28. # remote_branch = rest.split(' ')[0]
  29. pass
  30. else:
  31. # ahead or behind
  32. divergence = ' '.join(rest.split(' ')[1:])
  33. divergence = divergence.lstrip('[').rstrip(']')
  34. for div in divergence.split(', '):
  35. if 'ahead' in div:
  36. ahead = int(div[len('ahead '):].strip())
  37. elif 'behind' in div:
  38. behind = int(div[len('behind '):].strip())
  39. elif st[0] == '?' and st[1] == '?':
  40. untracked.append(st)
  41. else:
  42. if st[1] == 'M':
  43. changed.append(st)
  44. if st[0] == 'U':
  45. conflicts.append(st)
  46. elif st[0] != ' ':
  47. staged.append(st)
  48. out = ' '.join([
  49. branch,
  50. str(ahead),
  51. str(behind),
  52. str(len(staged)),
  53. str(len(conflicts)),
  54. str(len(changed)),
  55. str(len(untracked)),
  56. ])
  57. print(out, end='')