Skip to content

Instantly share code, notes, and snippets.

@derekpappas
Created December 24, 2022 14:52
Show Gist options
  • Select an option

  • Save derekpappas/6aed6a3dca80ce68f2622a08aaedacd4 to your computer and use it in GitHub Desktop.

Select an option

Save derekpappas/6aed6a3dca80ce68f2622a08aaedacd4 to your computer and use it in GitHub Desktop.

Revisions

  1. derekpappas created this gist Dec 24, 2022.
    140 changes: 140 additions & 0 deletions gitAddCommitPush.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,140 @@
    #!/usr/bin/env python3

    # Most of the code in this script was generated with Github copilot
    # I had to debug/fix some things...
    # This script adds, commits and pushes all changes to the git repository
    # It is intended to be used as a git hook, but can also be used as a standalone script
    # 1. Check that the script is called from a git repository
    # 2. Check that the current branch is not master or develop
    # 3. Check that the current branch is not behind develop
    # 4. Check that the current branch is not ahead of develop
    # 5. Check if there are any untracked files, modified files or files to be committed
    # 6. If there are any untracked files, modified files or files to be committed, ask the user if he wants to add, commit and push
    # 7. If the user wants to add, commit and push, add, commit and push all changes to the git repository
    # 8. git push --set-upstream origin <current branch> else git push

    import os
    import sys
    import subprocess
    import time

    # Check that the script is called from a git repository
    def checkGitRepository():
    if not os.path.exists('.git'):
    print('This script must be called from a git repository')
    sys.exit(1)

    # Check that the current branch is not master or develop
    def checkCurrentBranch():
    currentBranch = subprocess.check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD'])
    currentBranch = currentBranch.decode('utf-8').strip()
    if currentBranch == 'master' or currentBranch == 'develop':
    print('This script cannot be run on the master or develop branch')
    sys.exit(1)

    # Check that the current branch is not behind develop
    def checkCurrentBranchBehindDevelop():
    currentBranch = subprocess.check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD'])
    currentBranch = currentBranch.decode('utf-8').strip()
    developBranch = subprocess.check_output(['git', 'rev-parse', '--abbrev-ref', 'develop'])
    developBranch = developBranch.decode('utf-8').strip()
    behindDevelop = subprocess.check_output(['git', 'rev-list', '--left-right', '--count', currentBranch + '...' + developBranch])
    behindDevelop = behindDevelop.decode('utf-8').strip()
    behindDevelop = behindDevelop.split('\t')
    if behindDevelop[0] != '0':
    print('This script cannot be run if the current branch is behind the develop branch')
    print('Please pull the latest changes from the develop branch')
    print('git pull origin develop')
    sys.exit(1)

    # Check that the current branch is not ahead of develop
    def checkCurrentBranchAheadDevelop():
    currentBranch = subprocess.check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD'])
    currentBranch = currentBranch.decode('utf-8').strip()
    developBranch = subprocess.check_output(['git', 'rev-parse', '--abbrev-ref', 'develop'])
    developBranch = developBranch.decode('utf-8').strip()
    aheadDevelop = subprocess.check_output(['git', 'rev-list', '--left-right', '--count', currentBranch + '...' + developBranch])
    aheadDevelop = aheadDevelop.decode('utf-8').strip()
    aheadDevelop = aheadDevelop.split('\t')
    if aheadDevelop[1] != '0':
    print('This script cannot be run if the current branch is ahead of the develop branch')
    print('Please pull the latest changes from the develop branch')
    print('git pull origin develop')
    sys.exit(1)

    # Check if there are any untracked files, modified files or files to be committed
    # Print the list of untracked files, modified files and files to be committed
    def checkUntrackedModifiedFiles():
    untrackedFiles = subprocess.check_output(['git', 'ls-files', '--others', '--exclude-standard'])
    untrackedFiles = untrackedFiles.decode('utf-8').strip()
    modifiedFiles = subprocess.check_output(['git', 'diff', '--name-only'])
    modifiedFiles = modifiedFiles.decode('utf-8').strip()
    filesToBeCommitted = subprocess.check_output(['git', 'diff', '--cached', '--name-only'])
    filesToBeCommitted = filesToBeCommitted.decode('utf-8').strip()
    if untrackedFiles or modifiedFiles or filesToBeCommitted:
    if untrackedFiles:
    print('Untracked files:')
    print(untrackedFiles)
    if modifiedFiles:
    print('Modified files:')
    print(modifiedFiles)
    if filesToBeCommitted:
    print('Files to be committed:')
    print(filesToBeCommitted)
    return True
    else:
    return False


    # If there are any untracked files, modified files or files to be committed, ask the user if he wants to add, commit and push
    def askUserToAddCommitPush():
    print('There are untracked files, modified files or files to be committed')
    subprocess.call(['git', 'status'])
    print('Do you want to add, commit and push all changes to the git repository? (y/n)')
    addCommitPush = input("Enter your choice: [y/n] ")
    if addCommitPush == 'y':
    return True
    else:
    return False

    # If the user wants to add, commit and push, add, commit and push all changes to the git repository
    def addCommitPush(commitMessage):
    currentBranch = subprocess.check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD'])
    currentBranch = currentBranch.decode('utf-8').strip()
    subprocess.call(['git', 'add', '-A'])
    subprocess.call(['git', 'commit', '-m', commitMessage])
    subprocess.call(['git', 'push', '--set-upstream', 'origin', currentBranch])

    # If this is the first time the script is run then git push --set-upstream origin <current branch> else git push
    def push():
    currentBranch = subprocess.check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD'])
    currentBranch = currentBranch.decode('utf-8').strip()
    subprocess.call(['git', 'push', '--set-upstream', 'origin', currentBranch])

    # Main function
    def main():
    #check that the user provided a commit message as a program argument
    if len(sys.argv) != 2:
    print('Usage: python3 gitPush.py <commit message>')
    sys.exit(1)
    commitMessage = sys.argv[1]

    # assign a Python variable to the root of the the git repository
    gitRoot = subprocess.check_output(['git', 'rev-parse', '--show-toplevel'])
    gitRoot = gitRoot.decode('utf-8').strip()
    os.chdir(gitRoot)
    checkGitRepository()
    checkCurrentBranch()
    #checkCurrentBranchBehindDevelop()
    checkCurrentBranchAheadDevelop()
    if checkUntrackedModifiedFiles():
    if askUserToAddCommitPush():
    addCommitPush(commitMessage)
    else:
    push()

    if __name__ == '__main__':
    main()