2017-07-24 6 views
1

J'utilise python-git dans l'un de mes projets, et actuellement je ce code:Impossible d'exécuter git brut filtre branche

tpl = """ 
    if test $GIT_COMMIT = "%s"; then 
     export GIT_AUTHOR_DATE="%s" 
     export GIT_COMMITTER_DATE="%s" 
    fi 
""" 

s = "" 
for commit in filter(lambda x: x["newdatetime"] is not None, self.commit_datetime): 
    s += tpl % (
     commit["hash"], 
     commit["newdatetime"].replace(tzinfo = None), 
     commit["newdatetime"].replace(tzinfo = None) 
    ) 
cmd = "'%s'" % s 
cmd = re.compile("(?<=')\s+(?=\S)").sub("", cmd) 
cmd = re.compile("(?<=\S)\s+(?=')").sub("", cmd) 
self.git.repo.git.filter_branch("-f", "--env-filter \\\n", cmd) 

Par souci de cette question, accepter que le résultat de la fonction de lambda est un tableau d'un seul élément avec les données suivantes:

{ 
    "hash": "random git hash", 
    "newdatetime": "datetime string parseable by git filter branch" 
} 

les 2 re commandes sont utilisées pour dépouiller arrière et avant des espaces vides avant et après le premier/dernier caractère '.

Le résultat final est:

git.exc.GitCommandError: Cmd('git') failed due to: exit code(1) 
cmdline: git filter-branch -f --env-filter \ 
'if test $GIT_COMMIT = "64436207f36dd78e128936bbdec16b8741ff418c"; then 
     export GIT_AUTHOR_DATE="2017-07-24 18:56:26" 
     export GIT_COMMITTER_DATE="2017-07-24 18:56:26" 
fi' 
stderr: 'usage: git filter-branch [--env-filter <command>] [--tree-filter <command>] 
    [--index-filter <command>] [--parent-filter <command>] 
    [--msg-filter <command>] [--commit-filter <command>] 
    [--tag-name-filter <command>] [--subdirectory-filter <directory>] 
    [--original <namespace>] [-d <directory>] [-f | --force] 
    [<rev-list options>...]' 

La commande semble bien, et l'exécuter dans un shell fonctionne comme prévu, très bien. Soit git-python fait quelque chose de funky, soit il me manque une erreur (probablement) très simple. Laquelle est-ce?

EDIT:

Je mis à jour le code, maintenant il ressemble:

tpl = """ 
    if [ "$GIT_COMMIT" == "%s" ]; then 
     export GIT_AUTHOR_DATE="%s"; 
     export GIT_COMMITTER_DATE="%s"; 
    fi 
""" 
... 
... 
self.repo.git.filter_branch("-f", "--env-filter", cmd) 

Et maintenant, je reçois:

Traceback (most recent call last): 
    File "/Users/alexandernst/Proyectos/git-rewrite-date/git_rewrite_date.py", line 135, in rewrite 
    self.mygit.rewrite_dates(commits) 
    File "/Users/alexandernst/Proyectos/git-rewrite-date/my_git.py", line 38, in rewrite_dates 

    self.repo.git.filter_branch("-f", "--env-filter", cmd) 
    File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/git/cmd.py", line 425, in <lambda> 
    return lambda *args, **kwargs: self._call_process(name, *args, **kwargs) 
    File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/git/cmd.py", line 877, in _call_process 
    return self.execute(call, **exec_kwargs) 
    File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/git/cmd.py", line 688, in execute 
    raise GitCommandError(command, status, stderr_value, stdout_value) 
git.exc.GitCommandError: Cmd('git') failed due to: exit code(1) 
    cmdline: git filter-branch -f --env-filter 'if [ "$GIT_COMMIT" == "0694755bb844e5b5a569b56ee5154232265ccfe6" ]; then 
     export GIT_AUTHOR_DATE="2017-07-24 22:43:54"; 
     export GIT_COMMITTER_DATE="2017-07-24 22:43:54"; 
fi' 
Rewrite 8cbb2c9143ed58722d001b5c4f0e801636dbd079 (1/25) (0 seconds passed, remaining 0 predicted) ' 
    stderr: '/Applications/Xcode.app/Contents/Developer/usr/libexec/git-core/git-filter-branch: line 354: if [ "$GIT_COMMIT" == "0694755bb844e5b5a569b56ee5154232265ccfe6" ]; then 
     export GIT_AUTHOR_DATE="2017-07-24 22:43:54"; 
     export GIT_COMMITTER_DATE="2017-07-24 22:43:54"; 
fi: command not found 
env filter failed: 'if [ "$GIT_COMMIT" == "0694755bb844e5b5a569b56ee5154232265ccfe6" ]; then 
     export GIT_AUTHOR_DATE="2017-07-24 22:43:54"; 
     export GIT_COMMITTER_DATE="2017-07-24 22:43:54"; 
fi'' 

Notez que je reçois des progrès là-dedans, où il est dit "Réécrire 8cbb2 .... (1/25)". Cela signifie qu'il exécute la commande, mais il échoue pour une raison étrange.

+0

commentaire Side : il n'y a pas besoin d'appeler 're.compile' directement; toutes les opérations sur une expression compilée peuvent être invoquées sur une chaîne, par exemple, 're.sub (motif, repl, chaîne, nombre = 0, drapeaux = 0)'. – torek

Répondre

0

Je suspecte que le problème est dans "--env-filter \\\n". Je pense que la commande doit être juste

self.git.repo.git.filter_branch("-f", "--env-filter", cmd) 
+0

Je progresse dans ce sens. Maintenant, je vois l'erreur '' fi ': command not found'. Des idées? – alexandernst

+0

J'ai ajouté une deuxième réponse. – phd

0

Je pense aussi subprocess (utilisé au fond de GitPython) font de ce

tpl = """ 
    if test $GIT_COMMIT = "%s"; then 
     export GIT_AUTHOR_DATE="%s" 
     export GIT_COMMITTER_DATE="%s" 
    fi 
""" 

une ligne. Vous devez donc corriger la syntaxe bash dans le cas où il n'y a pas des sauts de ligne:

tpl = """ 
    if test $GIT_COMMIT = "%s"; then 
     export GIT_AUTHOR_DATE="%s"; 
     export GIT_COMMITTER_DATE="%s"; 
    fi 
""" 

(ajouter ; en place de nouvelles lignes).

+0

Je reçois toujours 'fi: commande non trouvée'. Mon instinct me dit qu'il y a une mauvaise syntaxe bash (ou quelque chose que l'interpréteur 'subprocess' utilise), mais je ne peux pas le voir. – alexandernst

+0

S'il vous plaît vérifier ma modification. – alexandernst

1

J'ai été capable de résoudre ce problème dans mon propre projet en utilisant subprocess et la syntaxe bash que vous avez dans votre mise à jour (avec des points-virgules et des crochets).

Peut-être que c'est juste le .strip() ajouté sur ma chaîne multiligne qui l'a corrigé?

Voici le code brut:

from subprocess import Popen, PIPE 

def set_commit_date(repo_dir: str, commit: str, new_date: str): 
    command = [ 
     '/usr/bin/git', 'filter-branch', '--env-filter', 
     f""" 
     if [ $GIT_COMMIT = {commit} ]; 
     then 
      export GIT_AUTHOR_DATE="{new_date}"; 
      export GIT_COMMITTER_DATE="{new_date}"; 
     fi 
     """.strip() 
    ] 
    process = Popen(command, cwd=repo_dir, stdout=PIPE, stderr=PIPE) 

    result, error = process.communicate() 
    if error: 
     raise Exception(error.decode()) 

    print(result.decode()) 
    print(repo_dir) 
    print(commit) 
    print(new_date) 

Quand je lance ce contre un repo factice dans mes tests unitaires, je reçois la sortie suivante (succès) des args suivants:

Rewrite 1f05fc01ffc790f5a32a918a0149f5096b5edaac (1/1) (0 seconds passed, remaining 0 predicted)  
Ref 'refs/heads/master' was rewritten 

/tmp/tmp7zzep_dz/testrepo 

1f05fc01ffc790f5a32a918a0149f5096b5edaac 

Sun, 03 Sep 2017 00:00:00 -0400