2009-04-02 7 views
3

Chaque fois que je veux prendre un sous-ensemble d'un patch, je suis obligé d'écrire un script pour extraire seulement les index que je veux.Comment extraire-t-on un sous-ensemble de patch de style unifified-diff?

par exemple. J'ai un patch qui s'applique aux sous-répertoires 'yay' et 'foo'.

Existe-t-il un moyen de créer un nouveau correctif ou d'appliquer uniquement un sous-ensemble d'un correctif? c'est-à-dire créer un nouveau correctif à partir du correctif existant qui ne prend que tous les index qui se trouvent dans le sous-répertoire "yay". Ou tous les indices qui ne sont pas sous sous-répertoire « 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 je le script une solution que je vais réinventer la roue ...

Répondre

3

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 
1

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 
+0

:-) Yah. J'en ai déjà fait quelques-uns ... J'espérais que le gourou d'Unix pourrait me dire "oh ouais, c'est la commande bla". –

+0

Il ne devrait pas être trop difficile de transformer cela en un utilitaire généraliste. par exemple. "patch-grep regex", où regex est appliqué aux noms de fichiers dans le patch. – sigjuice

+0

Vous avez raison. Je suis parti et fait ce que tu as suggéré. Seulement en * python * (que les guerres saintes commencent!) –

1

En réponse à la demande de sigjuice dans les commentaires, je poste ma solution de script. Ce n'est pas 100% à l'é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()