2012-02-07 15 views
5

多くのgitリポジトリで著者の書き直しを自動化するスクリプトがあります。Pythonサブプロセスのコマンドを実行します.Popen

def filter_history(old, new, name, repoPath): 

command = """--env-filter ' 
     an="$GIT_AUTHOR_NAME" 
     am="$GIT_AUTHOR_EMAIL" 
     cn="$GIT_COMMITTER_NAME" 
     cm="$GIT_COMMITTER_EMAIL" 

     if [[ "$GIT_COMMITTER_NAME" = "|old|" ]] 
     then 
      cn="|name|" 
      cm="|new|" 
     fi 

     if [[ "$GIT_AUTHOR_NAME" = "|old|" ]] 
     then 
      an="|name|" 
      am="|new|" 
     fi 

     export GIT_AUTHOR_NAME="$an" 
     export GIT_AUTHOR_EMAIL="$am" 
     export GIT_COMMITTER_NAME="$cn" 
     export GIT_COMMITTER_EMAIL="$cm" 
' 
""" 

#DO string replace 
command = command.replace("|old|", old) 
command = command.replace("|new|", new) 
command = command.replace("|name|", name) 

print "git filter-branch -f " + command 

process = subprocess.Popen(['git filter-branch -f', command],cwd=os.path.dirname(repoPath), shell=True) 
process.wait() 

コマンドは正常に実行されますが、リポジトリの履歴に何も変更されていないことがわかります。しかし、(実行されているはずのものである)印刷されたコマンドをシェルスクリプトにドロップして実行すると、履歴が正常に変更されます。私はコマンドが何とか正しく実行されていないと思う。サブプロセスモジュールがどのコマンドを実行しているかを正確に確認する方法はありますか?

答えて

5

shell = Trueを使用すると、subprocess.Popenには最初の引数として文字列が必要です。助けがあればshell = Trueを使用しないほうがいいです。なぜなら、それはsecurity risk (see the Warningになる可能性があるからです。

shell = Trueを省略するか、shell = Falseを使用すると、subprocess.Popenには引数のリストが必要です。文字列から引数のリストを生成するには、shlex.split

import shlex 
import subprocess 

def filter_history(old, new, name, repoPath): 
    """Change author info 
    """ 
    # http://help.github.com/change-author-info/ 
    # http://stackoverflow.com/a/3880493/190597 
    command = """git filter-branch -f --env-filter ' 
     an="$GIT_AUTHOR_NAME" 
     am="$GIT_AUTHOR_EMAIL" 
     cn="$GIT_COMMITTER_NAME" 
     cm="$GIT_COMMITTER_EMAIL" 

     if [[ "$GIT_COMMITTER_NAME" = "{old}" ]] 
     then 
      cn="{name}" 
      cm="{new}" 
     fi 

     if [[ "$GIT_AUTHOR_NAME" = "{old}" ]] 
     then 
      an="{name}" 
      am="{new}" 
     fi 

     export GIT_AUTHOR_NAME="$an" 
     export GIT_AUTHOR_EMAIL="$am" 
     export GIT_COMMITTER_NAME="$cn" 
     export GIT_COMMITTER_EMAIL="$cm" 
     ' 
     """.format(old = old, new = new, name = name) 

    process = subprocess.Popen(
     shlex.split(command), 
     cwd = os.path.dirname(repoPath)) 
    process.communicate() 
関連する問題