├── .github └── workflows │ └── pythonpackage.yml ├── LICENSE ├── README.md ├── requirements.txt └── src ├── git-base-branch ├── git-bpl ├── git-cb ├── git-ch ├── git-chistory ├── git-do ├── git-exec ├── git-home ├── git-save ├── git-strreplace ├── git-tig ├── git-update-feature-branch ├── git-use-template └── git-wip /.github/workflows/pythonpackage.yml: -------------------------------------------------------------------------------- 1 | name: Python package 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | strategy: 10 | max-parallel: 4 11 | matrix: 12 | python-version: [2.7, 3.5, 3.6, 3.7] 13 | 14 | steps: 15 | - uses: actions/checkout@v1 16 | - name: Set up Python ${{ matrix.python-version }} 17 | uses: actions/setup-python@v1 18 | with: 19 | python-version: ${{ matrix.python-version }} 20 | - name: Install dependencies 21 | run: | 22 | python -m pip install --upgrade pip 23 | pip install -r requirements.txt 24 | - name: Lint with flake8 25 | run: | 26 | pip install flake8 27 | # stop the build if there are Python syntax errors or undefined names 28 | flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics 29 | # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide 30 | flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2019 himanoa 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## git subcommands 2 | 3 | ### これなに? 4 | 5 | ひまのあのgit subcommand集 6 | 7 | ### Installation 8 | 9 | TBA 10 | 11 | ### LICENSE 12 | 13 | MIT 14 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himanoa/git-subcommands/3ea0bc619c2bd8398ff595eea357046953dd4675/requirements.txt -------------------------------------------------------------------------------- /src/git-base-branch: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from argparse import ArgumentParser 4 | import os 5 | def parser(): 6 | usage = 'Usage: git base-branch [-a ]' 7 | argparser = ArgumentParser(usage=usage) 8 | argparser.add_argument('-a', '--add', type=str, 9 | dest='branch_name', 10 | help='set base branch') 11 | args = argparser.parse_args() 12 | if args.branch_name: 13 | with open("BASE_BRANCH", "w") as f: 14 | f.write(args.branch_name) 15 | return 16 | try: 17 | with open("BASE_BRANCH", "r") as f: 18 | print(f.read(), end="") 19 | except: 20 | print("master", end="") 21 | 22 | if __name__ == '__main__': 23 | parser() 24 | 25 | -------------------------------------------------------------------------------- /src/git-bpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | git pull origin $(git base-branch) 4 | -------------------------------------------------------------------------------- /src/git-cb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from subprocess import check_output 4 | from argparse import ArgumentParser 5 | 6 | ''' 7 | ## Example 8 | 9 | ``` 10 | $ git symbolic-ref --short HEAD 11 | foobar 12 | $ git cb poepoe 13 | foobar/poepoe 14 | 15 | ### if current branch name === BASE_BRANCH 16 | $ git cb poepoe 17 | $ git symbolic-ref --short HEAD 18 | poepoe 19 | ``` 20 | ''' 21 | 22 | 23 | def base_branch(): 24 | check_output(['git', 'base-branch']) 25 | 26 | 27 | def current_branch(): 28 | return check_output( 29 | ['git', 'symbolic-ref', '--short', 'HEAD'] 30 | ).decode('utf-8').strip() 31 | 32 | 33 | if __name__ == "__main__": 34 | usage = 'Usage: git cb ' 35 | argparser = ArgumentParser(usage=usage) 36 | argparser.add_argument('branch_name', help='create branch name', type=str) 37 | args = argparser.parse_args() 38 | 39 | new_branch_name = args.branch_name 40 | if current_branch() == base_branch(): 41 | check_output(['git', 'checkout', '-b', new_branch_name]) 42 | else: 43 | check_output( 44 | ['git', 'checkout', '-b', "{0}__{1}".format( 45 | current_branch(), 46 | new_branch_name 47 | )] 48 | ) 49 | -------------------------------------------------------------------------------- /src/git-ch: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | git checkout $(git chistory | fzf-tmux) 4 | -------------------------------------------------------------------------------- /src/git-chistory: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from re import compile, match 4 | from subprocess import check_output 5 | 6 | ''' 7 | ## Example 8 | 9 | ``` 10 | $ git checkout -b foobar 11 | $ git checkout -b poepoe 12 | $ git checkout master 13 | $ git chistory 14 | foobar 15 | poepoe 16 | master 17 | ``` 18 | ''' 19 | 20 | REFLOG_REGEX = compile( 21 | '[a-z0-9]{9} HEAD@\{[1-9][0-9]*\}: checkout: moving from (.+) to (.+)' 22 | ) 23 | 24 | 25 | def parse_checkout_reflog(reflogs): 26 | def parse_ref(line): 27 | matched = REFLOG_REGEX.match(line) 28 | return {"from": matched[1], "to": matched[2]} 29 | return [parse_ref(reflog) for reflog in reflogs] 30 | 31 | 32 | if __name__ == "__main__": 33 | reflog = [ 34 | x for x in check_output(['git', 'reflog']) 35 | .decode('utf-8').split('\n')[:-1:] 36 | if REFLOG_REGEX.match(x) 37 | ] 38 | parsed = parse_checkout_reflog(reflog) 39 | for log in parsed: 40 | print(log.get("to")) 41 | -------------------------------------------------------------------------------- /src/git-do: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [ -z "$1" ]; then 4 | echo "commit message is empty" 5 | exit 1 6 | fi 7 | git commit --allow-empty -m "doing: $1" 8 | -------------------------------------------------------------------------------- /src/git-exec: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from argparse import ArgumentParser 4 | import os 5 | import subprocess 6 | 7 | BLACK = '\033[30m' 8 | RED = '\033[31m' 9 | GREEN = '\033[32m' 10 | YELLOW = '\033[33m' 11 | BLUE = '\033[34m' 12 | PURPLE = '\033[35m' 13 | CYAN = '\033[36m' 14 | WHITE = '\033[37m' 15 | END = '\033[0m' 16 | BOLD = '\038[1m' 17 | UNDERLINE = '\033[4m' 18 | INVISIBLE = '\033[08m' 19 | REVERCE = '\033[07m' 20 | 21 | def parser(): 22 | usage = 'Usage: git exec [...argv]' 23 | argparser = ArgumentParser(usage=usage) 24 | argparser.add_argument('command_name', help='Execute command', nargs="*") 25 | command = " ".join(argparser.parse_args().command_name) 26 | print("{0}Execute: {1}{2}".format(GREEN, command, END)) 27 | result = subprocess.call(command, shell=True) 28 | if(result == 1): 29 | return 30 | msg = "Exec `{}`".format(command, shell=True) 31 | print("{0}Add staging files{1}".format(GREEN, END)) 32 | subprocess.call("git add .", shell=True) 33 | print("{0}Commit: {1}{2}".format(GREEN, msg, END)) 34 | print("git commit -m '{}'".format(msg)) 35 | subprocess.call("git commit -m '{}'".format(msg), shell=True) 36 | 37 | if __name__ == '__main__': 38 | parser() 39 | 40 | -------------------------------------------------------------------------------- /src/git-home: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | git checkout $(git base-branch) 4 | -------------------------------------------------------------------------------- /src/git-save: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | wip_commit=$(git log --grep="^doing:" -n1 --format=%H) 4 | git commit --fixup "$wip_commit" 5 | git rebase -i --autosquash "$wip_commit"~1 6 | -------------------------------------------------------------------------------- /src/git-strreplace: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | ''' 4 | ## Example 5 | $ cat foobar.txt 6 | poepoe 7 | $ git grep popeoe 8 | foobar.txt 9 | 10 | $ git strreplace poepoe himanoa 11 | 12 | $ cat foobar.txt 13 | himanoa 14 | ''' 15 | 16 | import re 17 | 18 | BLACK = '\033[30m' 19 | RED = '\033[31m' 20 | GREEN = '\033[32m' 21 | YELLOW = '\033[33m' 22 | BLUE = '\033[34m' 23 | PURPLE = '\033[35m' 24 | CYAN = '\033[36m' 25 | WHITE = '\033[37m' 26 | END = '\033[0m' 27 | BOLD = '\038[1m' 28 | UNDERLINE = '\033[4m' 29 | INVISIBLE = '\033[08m' 30 | REVERCE = '\033[07m' 31 | 32 | from argparse import ArgumentParser 33 | from subprocess import check_output 34 | import os 35 | 36 | def execute(): 37 | try: 38 | usage = 'Usage: git strreplace [-w] ' 39 | argparser = ArgumentParser(usage=usage) 40 | argparser.add_argument('-w', '--word-regexp', action='store_true') 41 | argparser.add_argument('sub_string', 42 | help='sub_string', 43 | type=str, 44 | ) 45 | argparser.add_argument( 46 | 'replacement_string', 47 | help='replacement_string', 48 | type=str, 49 | ) 50 | args = argparser.parse_args() 51 | 52 | options = ['-l'] 53 | if args.word_regexp: 54 | options.append('-w') 55 | 56 | replace_target = check_output(['git', 'grep'] + options + [args.sub_string]).decode('utf-8').split('\n')[:-1:] 57 | for t in replace_target: 58 | with open(t, "r") as f: 59 | if args.word_regexp: 60 | pattern = r"\b" + re.escape(args.sub_string) + r"\b" 61 | else: 62 | pattern = re.escape(args.sub_string) 63 | file_body = re.sub(pattern, args.replacement_string, f.read()) 64 | with open(t, "w") as f: 65 | f.write(file_body) 66 | 67 | except: 68 | print('asd') 69 | 70 | if __name__ == '__main__': 71 | execute() 72 | 73 | -------------------------------------------------------------------------------- /src/git-tig: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | git add -N . && tig 3 | -------------------------------------------------------------------------------- /src/git-update-feature-branch: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "feature-branch: $1" 4 | echo "base-branch: $2" 5 | 6 | git checkout $2 7 | git pull origin $2 8 | git checkout $1 9 | git branch -D update-$1 10 | git checkout -b update-$1 11 | git merge $2 12 | git push origin update-$1 && gh pr create --title "update $1" --body "update $1" --base $1 13 | 14 | -------------------------------------------------------------------------------- /src/git-use-template: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | 4 | usage() 5 | { 6 | echo "Usage: git use-template [-h] template_name" 7 | exit 2 8 | } 9 | 10 | use_template() { 11 | local temp_dir 12 | temp_dir=$(mktemp -d) 13 | git clone "$1" "$temp_dir" 14 | rm -rf "$temp_dir"/.git 15 | mv "$temp_dir"/* . 16 | rm -rf "$temp_dir" 17 | exit 0 18 | } 19 | 20 | while : 21 | do 22 | case $1 in 23 | "-h" | "--help" | "" ) usage shift ;; 24 | * ) use_template "$@" ;; 25 | esac 26 | done 27 | -------------------------------------------------------------------------------- /src/git-wip: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | git commit -am "WIP" 4 | 5 | --------------------------------------------------------------------------------