Skip to content

Instantly share code, notes, and snippets.

@cyfdecyf
Created December 2, 2015 12:38
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cyfdecyf/6192d7c56f3db9af2f24 to your computer and use it in GitHub Desktop.
Save cyfdecyf/6192d7c56f3db9af2f24 to your computer and use it in GitHub Desktop.
Convert git diff to svn patch compatible format.
#!/usr/bin/python
# Author: Chen Yufei
# Convert git diff to svn patch compatible format.
import subprocess
import sys
import re
def check_output(cmd):
return subprocess.check_output(cmd, shell=True)
# Get the tracking branch (if we're on a branch)
tracking_branch = check_output("git svn info | grep URL | sed -e 's/.*\/branches\///'").strip()
# If the tracking branch has 'URL' at the beginning, then the sed wasn't successful and
# we'll fall back to the svn-remote config option
if tracking_branch[0:3] == 'URL':
tracking_branch = check_output("git config --get svn-remote.svn.fetch | sed -e 's/.*:refs\/remotes\///'").strip()
# Get the highest revision number
revision = check_output("git svn info | awk '/Last Changed Rev:/ { print $4 }'").strip()
# Then do the diff from the highest revision on the current branch
# and masssage into SVN format
rev_list = check_output('git rev-list --date-order --max-count=1 %s' % tracking_branch)
diff_output = check_output("git diff --no-prefix %s" % rev_list)
re_diff_git = re.compile('^diff --git [^ ]+ ([^ ]+$)')
re_diff_file_mode = re.compile('.+ file mode [0-9]+$')
re_diff_stat = re.compile('^(@@ -[^ ]+ \+[^ ]+ @@).*$')
def is_diff_header(line, i):
if re_diff_git.match(line[i]):
if re_diff_file_mode.match(line[i+1]):
i += 1
if line[i+1].startswith('index ') and \
line[i+2].startswith('--- ') and \
line[i+3].startswith('+++ '):
return True
return False
def convert_print_diff_header(line, i):
num_line = 4
print re_diff_git.sub(r'Index: \1', line[i])
if re_diff_file_mode.match(line[i+1]):
i += 1
num_line += 1
print '==================================================================='
if line[i+2] == '--- /dev/null':
filename = line[i+3][len('+++ '):]
print '--- %s\t(revision 0)' % filename
else:
print '%s\t(revision %s)' % (line[i+2], revision)
if line[i+3] == '+++ /dev/null':
filename = line[i+2][len('--- '):]
print '+++ %s\t(working copy)' % filename
else:
print '%s\t(working copy)' % line[i+3]
return num_line
i = 0
diff = diff_output.split('\n')
while i < len(diff):
if is_diff_header(diff, i):
i += convert_print_diff_header(diff, i)
elif re_diff_stat.match(diff[i]):
print re_diff_stat.sub(r'\1', diff[i])
i += 1
else:
if i == (len(diff) - 1):
# last line
sys.stdout.write(diff[i])
else:
print diff[i]
i += 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment