2012-02-07 46 views
5

Tôi có một tập lệnh tự động viết lại tác giả trên một số kho lưu trữ git.Lệnh thực thi in cho quy trình con Python. Mở

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() 

Lệnh này thực hiện tốt, nhưng cho tôi biết rằng không có gì thay đổi trong lịch sử repo. Tuy nhiên, nếu tôi lấy lệnh được in ra (mà nên là những gì đang được thực hiện), thả nó trong một kịch bản shell, và thực hiện nó, nó thay đổi tiền phạt lịch sử. Tôi nghĩ rằng lệnh này bằng cách nào đó không được thực hiện đúng. Có cách nào để xem chính xác lệnh nào mà mô đun subprocess đang thực thi không?

Trả lời

5

Khi bạn sử dụng shell = True, subprocess.Popen dự kiến ​​một chuỗi là đối số đầu tiên của nó. Tốt hơn là không nên sử dụng shell = True nếu bạn có thể trợ giúp vì nó có thể là security risk (see the Warning.

Khi bạn bỏ qua shell = True hoặc sử dụng shell = False, subprocess.Popen mong đợi một danh sách các đối số. Bạn có thể tạo danh sách đối số đó từ một chuỗi bằng cách sử dụng 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() 
Các vấn đề liên quan