Created
March 19, 2019 12:41
-
-
Save scambier/0c400a4fcd5f1f1bacc145c4c795ee32 to your computer and use it in GitHub Desktop.
Copy all changed files between two git commits. Respects the folders structure.
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 | |
| # Usage: python pyGitDiff.py hash1 hash2 | |
| # Help: python pyGitDiff.py -h | |
| import subprocess | |
| import os | |
| import shutil | |
| from datetime import datetime | |
| import argparse | |
| ignoreList = [".gitignore"] | |
| def main(): | |
| global ignoreList | |
| descString = "\nThis script will create a folder with all modified files between two git commits.\n" | |
| parser = argparse.ArgumentParser(description=descString) | |
| parser.add_argument( | |
| 'first_hash', | |
| help='the first commit\'s hash') | |
| parser.add_argument( | |
| 'second_hash', | |
| help='the 2nd commit\'s hash. Use HEAD for the latest commit') | |
| parser.add_argument( | |
| '-f', '--flat', | |
| help='don\'t copy directories', | |
| default=False, | |
| required=False, | |
| action='store_true') | |
| parser.add_argument( | |
| '-l', '--list', | |
| help='copy nothing, only show list', | |
| default=False, | |
| required=False, | |
| action='store_true') | |
| parser.add_argument( | |
| '-d', '--dest', | |
| metavar="folder", | |
| help='destination folder\'s name. If empty, a default name will be used', | |
| default=False, | |
| required=False) | |
| parser.add_argument( | |
| '-i', '--ignore', | |
| metavar="filename", | |
| help='files that you don\'t want to be copied (.gitignore will always be ignored)', | |
| nargs='*', | |
| required=False) | |
| args = vars(parser.parse_args()) | |
| commit1, commit2 = args['first_hash'], args['second_hash'] | |
| if args['ignore'] is not None: | |
| ignoreList += args['ignore'] | |
| # Get files list and split them in an array | |
| p = subprocess.Popen(["git", "diff", "--name-only", commit1, commit2], stdout=subprocess.PIPE) | |
| out, err = p.communicate() | |
| files = out.split("\n") | |
| # Remove the last empty line | |
| files.pop(len(files) - 1) | |
| if not args['dest']: | |
| folderName = "DIFF" | |
| folderName += datetime.now().strftime("_%Y-%m-%d_%Hh%M") | |
| folderName += "_" + commit1 + "-" + commit2 + "/" | |
| else: | |
| folderName = args['dest'] + '/' | |
| print ('\nList of modified files:\n') | |
| for file in files: | |
| print (file) | |
| if not args['list']: | |
| copyFile(file, folderName, args['flat']) | |
| if not args['list']: | |
| print('\nAll files are copied in folder "' + folderName + '"\n') | |
| def copyFile(file, dest, flat): | |
| global ignoreList | |
| struct = file.split('/') | |
| if len(struct) > 1: | |
| filename = struct.pop(len(struct) - 1) | |
| else: | |
| # File in root | |
| filename = file | |
| struct = [''] | |
| if filename in ignoreList: | |
| print (" -> ignored!") | |
| else: | |
| if flat: | |
| path = dest | |
| else: | |
| path = os.path.expanduser(dest + '/'.join(struct) + '/') | |
| if not os.path.exists(path): | |
| #Todo: make dir only if file exists | |
| try: | |
| with open(file) as f: | |
| os.makedirs(path) | |
| except IOError as e: | |
| # file doesn't exist, we don't make the dir | |
| pass | |
| try: | |
| shutil.copy(file, path + filename) | |
| print (" -> copied") | |
| except IOError as e: | |
| print (" -> deleted file") | |
| if __name__ == "__main__": | |
| main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment