summaryrefslogtreecommitdiffstats
path: root/bin/git-un-diff-whitespace
blob: 6338a47e7bcd08e8a0b5e074772f1e10b3db9f1f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#!/usr/bin/python

import os,sys,re,subprocess

hunk_re = re.compile(r'^@@ -\d+,\d+ \+(\d+),(\d+) @@')
ws_re = re.compile(r'^(.*?)[ \t]+$')
file_re = re.compile(r'^\-\-\- b/(.+)')

def strip_whitespace_regions(filename, hunks):
  if len(hunks) == 0:
    return
  filename_t = filename + '.tmp'
  tmpf = open(filename_t, 'w')
  f = open(filename)
  i = 0
  hunk = hunks[0]
  for line in f:
    if (hunk is None) or (i < hunk[0]):
      tmpf.write(line)
    elif i < (hunk[0] + hunk[1]):
      nline = ws_re.sub(r'\1', line) 
      tmpf.write(nline) 
    else:
      hunks = hunks[1:]
      if len(hunks) == 0:
        hunk = None
      else:
        hunk = hunks[0] 
      tmpf.write(line)
    i = i+1
  tmpf.close()
  f.close()
  os.rename(filename_t, filename)
  print "wrote " + filename

def main():
  toplevel = subprocess.Popen(['git', 'rev-parse', '--show-toplevel'], stdout=subprocess.PIPE).communicate()[0]
  os.chdir(toplevel[:-1])
  diff = subprocess.Popen(['git', 'diff'], stdout=subprocess.PIPE).communicate()[0]
  if diff != '':
    print "You have unstaged changes; Commit them or 'git stash'"
    sys.exit(1)
  commit_proc = subprocess.Popen(['git', 'show', '-p', 'HEAD'], stdout=subprocess.PIPE,
                                 stderr=sys.stderr)
  diff_lines = commit_proc.stdout.readlines()
  commit_proc.wait()
  subprocess.check_call(['git', 'reset', 'HEAD^'], stdout=sys.stdout, stderr=sys.stderr)
  curfile = None
  hunks = []
  files = []
  for line in diff_lines:
    if curfile is not None:
      match = hunk_re.match(line) 
      if match:
        hunks.append((int(match.group(1)),int(match.group(2))))
        continue
    match = file_re.match(line)
    if match:
      filename = match.group(1)
      strip_whitespace_regions(curfile, hunks)
      curfile = filename
      files.append(filename)
      hunks = []
  if curfile:
    strip_whitespace_regions(curfile, hunks)
  add_args = ['git', 'add']
  add_args.extend(files)
  subprocess.check_call(add_args, stdout=sys.stdout, stderr=sys.stderr)
  subprocess.check_call(['git', 'commit', '-c', 'ORIG_HEAD'], stdout=sys.stdout, stderr=sys.stderr)

if __name__ == '__main__':
  main()