Skip to content

Instantly share code, notes, and snippets.

@Lycolia
Created February 21, 2021 23:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Lycolia/13adba1292755ef2787ff69f64337720 to your computer and use it in GitHub Desktop.
Save Lycolia/13adba1292755ef2787ff69f64337720 to your computer and use it in GitHub Desktop.
git switch pull back branch with auto --skip-work-tree
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#region 環境
import sys
import subprocess
# トレースバック非表示
sys.tracebacklimit = 0
#endregion
#region 定数
# Gitのディレクトリ
GitDir = 'hoge'
# Gitのコマンドヘッダ
GitCmdHead = 'git -C ' + GitDir
#endregion
#region ユーティリティ
def gitCmd(*options):
"""Gitのコマンドを実行
Args:
*cmds (list): コマンドオプション
Returns:
list: 標準出力の行配列
"""
appendOptions = ''
for opt in options:
appendOptions += opt + ' '
runCommand = GitCmdHead + ' ' + appendOptions
print runCommand
runResult = subprocess.check_output(runCommand, shell=True).replace(' ', '').split()
return runResult
def readLine(message = '続けるにはキー入力して下さい'):
"""標準入力から一行入力を取得
Args:
message (str, optional): 表示するメッセージ. Defaults to '続けるにはキー入力して下さい'.
Returns:
str: 入力された文字列
"""
print message
return sys.stdin.readline().strip()
#endregion
#region ブランチ操作
def selectDistBranch():
"""スイッチ先のブランチ選択
Returns:
str: ブランチ名
"""
hitBranch = []
# 当たるまで繰り返し
while len(hitBranch) == 0:
branches = gitCmd('branch -a')
branchName = readLine('スイッチ先のブランチ名を入力して下さい')
hitBranch = [ branch for branch in branches if branchName == branch ]
if hitBranch:
return hitBranch[0]
else:
# ブランチリストアップ
for item in branches:
print item
print '存在しないブランチが選ばれました。上記リストからブランチを再入力して下さい'
def switchBranch(distBranch):
"""変更ファイルをスタッシュし、ブランチをスイッチし、PULL
Args:
distBranch (str): スイッチ先のブランチ名
"""
gitCmd('stash push -u -q -m changing_branch')
print '未変更を全てスタッシュしました'
gitCmd('ls-files -v | grep ^S | sed -r \'s/^S.(.+)$/\\1/g\' | xargs ', GitCmdHead, 'update-index --no-skip-worktree')
gitCmd('stash push -q -m stash_skiptree')
print '--skip-worktreeを全て解除し、スタッシュしました'
gitCmd('switch ' + distBranch)
pullResults = gitCmd('pull')
for item in pullResults:
print item
def backToMerge(distBranch):
"""元のブランチに戻ってマージ
"""
gitCmd('switch -')
'直前のブランチに戻りました'
try:
mergeResult = gitCmd('merge', distBranch)
print 'コンフリクトはありませんでした'
except Exception as ex:
# コンフリクトしてると例外が出る
readLine('コンフリクトを解消したらキー入力して下さい')
def restoreStash():
"""スタッシュを戻す
"""
# pop前のスタッシュリストを取得
beforeStashes = gitCmd('stash list')
gitCmd('stash pop')
print 'スタッシュから--skip-worktree分を復元しました'
# pop後のスタッシュリストを取得
afterStashes = gitCmd('stash list')
if len(beforeStashes) == len(afterStashes):
# pop前後でスタッシュ数が変わっていない=コンフリクト
readLine('コンフリクトを解消してキー入力して下さい')
gitCmd('stash drop')
print 'コンフリクトしていた--skip-worktree分をドロップしました'
gitCmd('reset')
print 'ステージングを解除しました'
gitCmd('diff --name-only HEAD | xargs', GitCmdHead, 'update-index --skip-worktree')
print '--skip-worktree分を--skip-worktreeしなおしました'
if len(afterStashes) > 0:
# 作業変更分があれば
gitCmd('stash pop')
print 'スタッシュから作業変更分を復元しました'
#endregion
#region エントリポイント
def main():
distBranch = selectDistBranch()
switchBranch(distBranch)
backToMerge(distBranch)
restoreStash()
if __name__ == '__main__':
try:
main()
except Exception as ex:
print '例外が発生しました'
print str(ex)
#endregion
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment