Skip to content

Instantly share code, notes, and snippets.

@stecman
Last active August 29, 2015 14:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stecman/957a00380cfc38b399c9 to your computer and use it in GitHub Desktop.
Save stecman/957a00380cfc38b399c9 to your computer and use it in GitHub Desktop.
Convert folders named d1, d2, d3, etc into git repository
#!/usr/bin/env python
#
# Convert "versioning" with folders called d1, d2, d3.. into a git repository in the directory
# containing those folders. Written for use on *nix systems for people who weren't using version
# control software for a long time.
import os
import re
import time
import sys
import argparse
import tempfile
from datetime import datetime
from subprocess import check_output, check_call
# Set up command line interface
parser = argparse.ArgumentParser(description='Convert d1, d2, d3.. style versioning into git repositories')
parser.add_argument('--path', '-p', default=os.getcwd(), help='Directory to run conversion in. Defaults to current working directory')
parser.add_argument('--author', '-a', default='Git Robot <robot@example.com>', help='Git commit author')
parser.add_argument('-v', '--verbose', action='store_true')
args = parser.parse_args()
GIT_AUTHOR = args.author
# Print a message for debugging
def debug(message):
if args.verbose:
print "%s: %s" % (datetime.now().strftime('%Y-%m-%d %H:%M:%S'), message)
# Ensure the given path exists
if not os.path.isdir(args.path):
print '%s is not a directory' % (args.path)
sys.exit(1)
debug('Working with %s' %os.path.abspath(args.path))
# Get dirs named in draft style
draft_folder = re.compile('d[0-9]+.*',re.IGNORECASE)
dirs = os.walk(args.path).next()[1]
dirs = filter(draft_folder.match, dirs)
dirs.sort()
debug("Matching directories: %s" % str(dirs))
# Bail out if not a draft-style directory parent
if len(dirs) == 0:
print 'No draft-style directories found in %s' % (args.path)
sys.exit(1)
# Set up temp directory
TEMP_DIR = tempfile.mkdtemp('', 'd2git-')
check_call(['git', 'init', TEMP_DIR])
# Loop through all d## folders (ascending) and commit each version to the temp repository
to_remove = []
commits = 0
for name in dirs:
path = os.path.abspath( os.path.join(args.path, name) )
date = time.strftime('%a %B %d %H:%M:%S %Y %z', time.localtime(os.path.getmtime(path)))
commit_msg = "%s (backdated, automated)" % (name)
debug('COMMIT (%s): %s' % (date, commit_msg))
# Copy directory to working copy
check_call(['rsync', '-a', '--delete', '--exclude=.git', path + "/", TEMP_DIR])
check_call(['git', '-C', TEMP_DIR, 'add', '--all', '.'])
try:
check_call(['git', '-C', TEMP_DIR, 'commit', '-a', '-m', commit_msg, '--author='+GIT_AUTHOR, '--date='+date])
except:
# Git writes to stderr, so the cause of this error will be known.
# This is usually caused by having no change in git's working dir
doContinue = raw_input("Git returned a non-zero code. Continue? y/N: ")
if(doContinue != "y" and doContinue !="Y"):
exit(1)
else:
pass
# Add the successfully processed dir to a removal list
to_remove.append(path)
# Delete any zip of the version that exists (these are unecessary and waste space)
zip_path = os.path.join(os.path.abspath(args.path), name + '.zip')
if os.path.isfile(zip_path):
to_remove.append(zip_path)
# Clean up and compact the new repo
check_call(['git', '-C', TEMP_DIR, 'gc'])
for path in to_remove:
debug('removing %s' % path)
check_call(['rm', '-rf', path])
# Move repository back into original directory and clean up the temp directory
debug('Syncing repository back to source')
check_call(['rsync', '-a', TEMP_DIR + '/', args.path])
debug('removing temp directory')
check_call(['rm', '-rf', TEMP_DIR])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment