Created
December 2, 2015 12:38
-
-
Save cyfdecyf/6192d7c56f3db9af2f24 to your computer and use it in GitHub Desktop.
Convert git diff to svn patch compatible format.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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