Vérifiez si un fichier ou un dossier a déjà été corrigé

22

Est-il possible de savoir si un fichier a déjà été patché, avant d'appliquer le patch?

Je dois le faire dans un script, des pensées?

Marguerite
la source
1
Quel programme utilisez-vous pour les patcher? Quel genre de patchs?
Omnifarious
1
La clé est "-R" - unix.stackexchange.com/a/86872/6622
poige

Réponses:

20

Oui, exécutez simplement patchavec --dry-runoption, il échouerait ou réussirait, ce qui peut être découvert avec son état de sortie.

Mais de manière plus courante (et sujette aux erreurs) , vous devez probablement l'exécuter avec l' -Roption qui signifie "inverser" car ce n'est que s'il était en mesure de rétablir la totalité du correctif qu'il pourrait être considéré comme "appliqué". Sinon (sans '-R'), il pourrait échouer simplement parce que certaines parties du fichier d'origine ont été modifiées. Voici un exemple simple:

if ! patch -R -p0 -s -f --dry-run <patchfile; then
  patch -p0 <patchfile
fi

(De plus, dans l'extrait ci-dessus, vous préférerez peut-être même réduire patchcomplètement au silence la redirection de sa stdout et de sa stderr /dev/null)

poige
la source
1
Cela ne fonctionne pas pour moi. Lorsque j'exécute cette commande, si le correctif n'a pas été appliqué, il demande s'il faut annuler la suppression du correctif en mode interactif et, si j'utilise le mode par lots, il ignorera l'opération inverse et appliquera le correctif, en retournant 0.
synack
1
Hé, essayez d'ajouter -sfà patch(peut être écrit comme patch -Rsfp0 --dry-run)
poige
1
@synack ça s'est bien passé?
poige
16

Juste au cas où cela aiderait quelqu'un, si vous utilisez un script bash, l'exemple donné par Omnifarious ne fonctionnerait pas. Dans bash, le statut de sortie d'une commande réussie est 0

Donc, ce qui suit fonctionnerait:

patch -p0 -N --dry-run --silent < patchfile 2>/dev/null
#If the patch has not been applied then the $? which is the exit status 
#for last command would have a success status code = 0
if [ $? -eq 0 ];
then
    #apply the patch
    patch -p0 -N < patchfile
fi
DivKis01
la source
La vérification devrait être contre 1au lieu de 0:if [ $? -eq 1 ]
Crisson
2
Non, 0 est correct. Le correctif se terminerait avec une valeur non nulle si l'exécution à sec échouait pour une raison quelconque, auquel cas le correctif ne devrait pas être appliqué.
Fls'Zen
Mon script était correct en bash. bash considère qu'un code de sortie de 0 est trueutilisé pour if. Précisément parce que la plupart des commandes utilisent un code de sortie de 0 pour indiquer le succès.
Omnifarious
2

Voici une supposition, en supposant que vous utilisez l' patchutilitaire et que chaque fichier à corriger a son propre correctif:

if patch <options> -N --dry-run --silent <patchfile 2>/dev/null; then
    echo The file has not had the patch applied,
    echo and the patch will apply cleanly.
else
    echo The file may not have had the patch applied.
    echo Or maybe the patch doesn't apply to the file.
fi
Très varié
la source
Ou, si vous avez patché les fichiers auparavant et que vous voulez savoir s'il a touché un fichier spécifique, vous pouvez exécuter le premier tour de patch avec l' -Boption, ce qui entraînerait la sauvegarde. Ensuite, vous vérifiez l'existence de la sauvegarde.
peterph
8
Pourriez-vous développer un peu pourquoi vous avez choisi d'utiliser nohupdans ce ifcas?
zrajm
@zrajm - Je ne me souviens pas pourquoi j'ai fait ça. Et au moment où j'ai remarqué (à cause d'une demande d'approbation de modification) qu'il était là, c'était il y a si longtemps qu'il n'y avait aucune chance que je récupère jamais la raison. Il me semble tout à fait inutile de le regarder maintenant.
Omnifarious
0

Dans mon cas, je voulais faire cette vérification pour que l'exécution de la commande patch ne se termine pas par un terminal interactif demandant quoi faire (en particulier pour CI).

Il s'avère que si vous n'en avez besoin que vous pouvez également utiliser l' --forwardargument et qu'il sautera le patch s'il est déjà appliqué!

maxime1992
la source
0

Cela a fonctionné pour moi.

"scripts": {
    "symfony-scripts": [
        "patch -N --silent -p0 < patches/vendor/somefile.js.patch &2>/dev/null",
        "Incenteev\\ParameterHandler\\ScriptHandler::buildParameters",
neisantos
la source