Skip to content

Instantly share code, notes, and snippets.

@krig
Last active June 21, 2018 20:48
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 krig/a67d8f0d65843a3ff237409f7d9a87e7 to your computer and use it in GitHub Desktop.
Save krig/a67d8f0d65843a3ff237409f7d9a87e7 to your computer and use it in GitHub Desktop.
Get files out of git-annex without any dependencies except Python 3
#!/usr/bin/python3
#
# A small utility for pulling files out of git-annex without
# actually having git-annex installed, with minimal
# dependencies.
import sys
import os
import argparse
import shutil
import hashlib
def print_win(f):
try:
print(f)
except UnicodeEncodeError:
print(f.encode('utf-8', 'surrogateescape').decode('ISO-8859-1'))
def parseargs():
parser = argparse.ArgumentParser(description='Extract files from a git-annex.')
parser.add_argument('--to', dest='output', required=True,
help='path to the output directory')
parser.add_argument('--from', dest='annex', required=True,
help='path to the git annex')
parser.add_argument('--action', dest='action', choices=['copy', 'move', 'none'], default='none',
help='action to perform for each file')
return parser.parse_args()
def do_copy(src, dst):
print_win("cp {} {}".format(src, dst))
try:
shutil.copy2(src, dst)
return True
except shutil.Error as err:
print(err)
return False
except PermissionError as err:
print(err)
return False
def do_remove(src):
print_win("rm {}".format(src))
try:
os.remove(src)
return True
except OSError as err:
print(err)
return False
def main():
args = parseargs()
output = args.output
annex = args.annex
action = args.action
tgttail = len(annex)
for dirpath, dirnames, filenames in os.walk(annex):
if dirpath.startswith(os.path.join(annex, ".git")):
continue
target = output + dirpath[tgttail:]
if not os.path.isdir(target):
print_win("mkdir {}".format(target))
if action in ['copy', 'move']:
os.mkdir(target)
for f in filenames:
src = os.path.join(dirpath, f)
dst = os.path.join(target, f)
if os.path.exists(dst):
if action == 'move' and os.path.exists(src):
print_win("md5sum {} ...".format(src))
m = hashlib.md5()
m.update(open(src, 'rb').read())
srcdigest = m.digest()
print_win("md5sum {} ...".format(dst))
m = hashlib.md5()
m.update(open(dst, 'rb').read())
dstdigest = m.digest()
if srcdigest == dstdigest:
if do_remove(dst) and do_copy(src, dst) and action == 'move':
do_remove(src)
else:
print_win("diff! ls -l \"{}\" \"{}\"".format(src, dst))
else:
if action in ['copy', 'move']:
if do_copy(src, dst) and action == 'move':
do_remove(src)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment