Skip to content

Instantly share code, notes, and snippets.

@mostlylikeable
Created March 6, 2021 03:40

Revisions

  1. mostlylikeable created this gist Mar 6, 2021.
    147 changes: 147 additions & 0 deletions git-migrate-up.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,147 @@
    #!/bin/bash
    # script for stashing and pushing all changes, stashes, local branches to remote/fork (origin)
    # so they can be pulled down on another machine.

    function _gm_not_dry_run() {
    return 1 # set to 0 to run
    }

    # recursively stash any pending changes for all subdirs where this is run
    function rstash() {
    echo "stashing recursively $PWD"
    find $PWD -maxdepth 1 -mindepth 1 -type d |while read dir; do
    cd $dir
    stash $dir
    cd ..
    done
    }

    function stash() {
    _gm_status_dry
    if _gm_is_git_repo; then
    if _gm_has_changes $PWD; then
    _gm_br_header
    _gm_status "stashing changes"
    if _gm_not_dry_run; then
    git stash save "rstash"
    git checkout main
    fi
    else
    _gm_br_header_ignored "no changes"
    fi
    else
    _gm_br_header_ignored "not git-repo"
    fi
    }

    function _gm_has_changes() {
    local changes=$(git diff --name-only)
    if [ ! -z $changes ]; then
    return 0
    else
    return 1
    fi
    }

    # recursively push all stashes and local branches to remote for all subdirs
    # where this is run
    function rpush_allthethings() {
    find $PWD -maxdepth 1 -mindepth 1 -type d | sort -t '\0' -n | while read dir; do
    cd $dir
    push_allthethings
    cd ..
    done
    }

    function push_allthethings() {
    _gm_status_dry

    if _gm_is_git_repo; then
    _gm_br_header
    push_stashes
    push_branches
    else
    _gm_br_header_ignored "not git-repo"
    fi
    }

    # pushes all stashes to origin branches
    # branche-names:
    # stash_<sha> (stash_4112ffa5)
    function push_stashes() {
    if _gm_has_stashes; then
    local stashes=()
    while IFS= read -r line; do
    stashes+=$(echo $line)
    done <<< "$(git reflog stash)" # ex: "bca6c994 stash@{0}: On use_object_type: migrate stash"

    _gm_status "push ${#stashes[@]} stashes to origin"
    for stash in "${stashes[@]}"; do
    local ref=$(echo $stash | awk '{print $1}')
    local desc=$(echo $stash | awk {'first = $1; $1=""; print $0'}|sed 's/^ //g')
    _gm_status "push stash - ${ref}:refs/heads/stash_${ref} ($desc)"
    if _gm_not_dry_run; then
    git push origin ${ref}:refs/heads/stash_${ref}
    fi
    done
    else
    echo "no stashes found"
    fi
    }

    function _gm_has_stashes() {
    [ ! -z "$(git stash list)" ] && return 0 || return 1
    }

    # pushes all local branches to origin
    function push_branches() {
    local branches=()
    eval "$(git for-each-ref --shell --format='branches+=(%(refname))' refs/heads/boggess)"
    if [ ! ${#branches[@]} -eq 0 ]; then
    _gm_status "push ${#branches[@]} branches to origin"
    for branch in "${branches[@]}"; do
    _gm_status "push local - $branch"
    if _gm_not_dry_run; then
    git push origin $branch
    fi
    done
    else
    echo "no branches found"
    fi
    }

    function _gm_br_header_ignored() {
    _gm_print_header "\e[0;37m" "($1)"
    }

    function _gm_br_header() {
    _gm_print_header "\e[1;42m"
    }

    function _gm_print_header() {
    local padlength=80
    local pad=$(printf '%0.1s' "#"{1..$padlength})
    local dir="# $(basename $PWD) $2"
    local color=$1
    local color_reset="\e[m"

    printf "\n$color%s$color_reset\n" "$pad"
    printf "$color%-$((padlength-1))s%s$color_reset\n" "$dir" "#"
    printf "$color%s$color_reset\n\n" "$pad"
    }

    function _gm_status() {
    echo "\033[1;32m> $1\033[0m"
    }

    function _gm_status_dry() {
    if _gm_not_dry_run; then
    echo ""
    else
    echo "-- dry run (enable in _gm_dry_run)"
    fi
    }

    function _gm_is_git_repo() {
    [ -d .git ] && return 0 || return 1
    }