Comment peut-on extrait un sous-ensemble de patch de style unifié diff?
Question
Chaque fois que je veux prendre un sous-ensemble d'un patch, je suis obligé d'écrire un script pour extraire uniquement les indices que je veux.
par exemple. J'ai un patch qui applique aux sous-répertoires 'Yay' et 'foo'.
Y at-il un moyen de créer un nouveau patch ou d'appliquer un sous-ensemble d'un patch? à savoir créer un nouveau patch du patch existant qui ne prend que tous les indices qui sont sous sous-répertoire « yay ». Ou tous les indices qui ne sont pas sous le répertoire sous « foo »
Si j'ai un patch comme (excusez le pseudo-patch ci-dessous):
Index : foo/bar
yada
yada
- asdf
+ jkl
yada
yada
Index : foo/bah
blah
blah
- 28
+ 29
blah
blah
blah
Index : yay/team
go
huskies
- happy happy
+ joy joy
cougars
suck
Comment puis-je extraire ou appliquer uniquement le sous-répertoire « yay » comme:
Index : yay/team
go
huskies
- happy happy
+ joy joy
cougars
suck
Je sais que si le script je une solution que je vais réinventer la roue ...
La solution
Jetez un oeil à l'utilitaire filterdiff
, qui fait partie de patchutils .
Par exemple, si vous avez le correctif suivant:
$ cat example.patch
diff -Naur orig/a/bar new/a/bar
--- orig/a/bar 2009-12-02 12:41:38.353745751 -0800
+++ new/a/bar 2009-12-02 12:42:17.845745951 -0800
@@ -1,3 +1,3 @@
4
-5
+e
6
diff -Naur orig/a/foo new/a/foo
--- orig/a/foo 2009-12-02 12:41:32.845745768 -0800
+++ new/a/foo 2009-12-02 12:42:25.697995617 -0800
@@ -1,3 +1,3 @@
1
2
-3
+c
diff -Naur orig/b/baz new/b/baz
--- orig/b/baz 2009-12-02 12:41:42.993745756 -0800
+++ new/b/baz 2009-12-02 12:42:37.585745735 -0800
@@ -1,3 +1,3 @@
-7
+z
8
9
Ensuite, vous pouvez exécuter la commande suivante pour extraire le patch pour que les choses dans le répertoire a
comme ceci:
$ cat example.patch | filterdiff -i 'new/a/*'
--- orig/a/bar 2009-12-02 12:41:38.353745751 -0800
+++ new/a/bar 2009-12-02 12:42:17.845745951 -0800
@@ -1,3 +1,3 @@
4
-5
+e
6
--- orig/a/foo 2009-12-02 12:41:32.845745768 -0800
+++ new/a/foo 2009-12-02 12:42:25.697995617 -0800
@@ -1,3 +1,3 @@
1
2
-3
+c
Autres conseils
Voici ma solution Perl rapide et sale.
perl -ne '@a = split /^Index :/m, join "", <>; END { for(@a) {print "Index :", $_ if (m, yay/team,)}}' < foo.patch
En réponse à la demande de sigjuice dans les commentaires, je poste ma solution de script. Il n'est pas 100% épreuve des balles, et je vais probablement utiliser filterdiff
à la place.
base_usage_str=r'''
python %prog index_regex patch_file
description:
Extracts all indices from a patch-file matching 'index_regex'
e.g.
python %prog '^evc_lib' p.patch > evc_lib_p.patch
Will extract all indices which begin with evc_lib.
-or-
python %prog '^(?!evc_lib)' p.patch > not_evc_lib_p.patch
Will extract all indices which do *not* begin with evc_lib.
authors:
Ross Rogers, 2009.04.02
'''
import re,os,sys
from optparse import OptionParser
def main():
parser = OptionParser(usage=base_usage_str)
(options, args) = parser.parse_args(args=sys.argv[1:])
if len(args) != 2:
parser.print_help()
if len(args) == 0:
sys.exit(0)
else:
sys.exit(1)
(index_regex,patch_file) = args
sys.stderr.write('Extracting patches for indices found by regex:%s\n'%index_regex)
#print 'user_regex',index_regex
user_index_match_regex = re.compile(index_regex)
# Index: verification/ring_td_cte/tests/mmio_wr_td_target.e
# --- sw/cfg/foo.xml 2009-04-30 17:59:11 -07:00
# +++ sw/cfg/foo.xml 2009-05-11 09:26:58 -07:00
index_cre = re.compile(r'''(?:(?<=^)|(?<=\n))(--- (?:.*\n){2,}?(?![ @\+\-]))''')
patch_file = open(patch_file,'r')
all_patch_sets = index_cre.findall(patch_file.read())
patch_file.close()
for file_edit in all_patch_sets:
# extract index subset
index_path = re.compile('\+\+\+ (?P<index>[\w_\-/\.]+)').search(file_edit).group('index').strip()
if user_index_match_regex.search(index_path):
sys.stderr.write("Index regex matched index: "+index_path+"\n")
print file_edit,
if __name__ == '__main__':
main()