Skip to content

Instantly share code, notes, and snippets.

@amakukha
Last active July 9, 2019 11:05
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 amakukha/4e3b7d5273f5c186d43a2eac95409f6c to your computer and use it in GitHub Desktop.
Save amakukha/4e3b7d5273f5c186d43a2eac95409f6c to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
import os, sys, hashlib
MD5 = True
def md5sum(fn):
hasher = hashlib.md5()
with open(fn, 'rb') as f:
hasher.update(f.read())
return hasher.hexdigest()
def compare_dirs(d1: "old directory name", d2: "new directory name"):
def print_local(a, msg):
print('DIR ' if a[2] else 'FILE', a[1], msg)
# ensure validity
for d in [d1,d2]:
if not os.path.isdir(d):
raise ValueError("not a directory: " + d)
# get relative path
l1 = [(x,os.path.join(d1,x)) for x in os.listdir(d1)]
l2 = [(x,os.path.join(d2,x)) for x in os.listdir(d2)]
# determine type: directory or file?
l1 = sorted([(x,y,os.path.isdir(y)) for x,y in l1])
l2 = sorted([(x,y,os.path.isdir(y)) for x,y in l2])
i1 = i2 = 0
cnt = 0
common_dirs = []
while i1<len(l1) and i2<len(l2):
if l1[i1][0] == l2[i2][0]: # same name
if l1[i1][2] == l2[i2][2]: # same type
if l1[i1][2]: # remember this folder for recursion
common_dirs.append((l1[i1][1], l2[i2][1]))
else:
# Compare file sizes
size1 = os.stat(l1[i1][1]).st_size
size2 = os.stat(l2[i2][1]).st_size
if size1!=size2:
print_local(l1[i1],'size changed: %d -> %d' % (size1, size2))
elif MD5:
if md5sum(l1[i1][1])!=md5sum(l2[i2][1]):
print_local(l1[i1],'hash changed')
else:
print_local(l1[i1],'type changed')
i1 += 1
i2 += 1
elif l1[i1][0]<l2[i2][0]:
print_local(l1[i1],'removed')
i1 += 1
elif l1[i1][0]>l2[i2][0]:
print_local(l2[i2],'added')
i2 += 1
cnt += 1
while i1<len(l1):
print_local(l1[i1],'removed')
i1 += 1
cnt += 1
while i2<len(l2):
print_local(l2[i2],'added')
i2 += 1
cnt += 1
# compare subfolders recursively
for sd1,sd2 in common_dirs:
cnt += compare_dirs(sd1, sd2)
return cnt
if __name__=="__main__":
if MD5: print ('MD5 checking enabled')
print (compare_dirs(sys.argv[1], sys.argv[2]), 'items compared')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment