Como o patch de um estilo de extrato a-diff unificado subconjunto?
Pergunta
Toda vez que eu quiser tomar um subconjunto de um patch, eu sou forçado a escrever um script para extrair apenas os índices que eu quero.
por exemplo. Eu tenho um patch que se aplica a sub-diretórios 'Yay' e 'foo'.
Existe uma maneira de criar um novo patch ou aplicar apenas um subconjunto de um patch? ou seja, criar um novo patch do patch existente que só leva todos os índices que estão sob sub diretório 'yay'. Ou todos os índices que não estão sob sub diretório 'foo'
Se eu tiver um patch como (desculpe o abaixo pseudo-patch):
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
Como posso extrair ou aplicar apenas o 'yay' subdiretório como:
Index : yay/team
go
huskies
- happy happy
+ joy joy
cougars
suck
Eu sei que se eu roteiro-se uma solução eu vou ser re-inventar a roda ...
Solução
Veja o utilitário filterdiff
, que faz parte do patchutils .
Por exemplo, se você tem o seguinte patch:
$ 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
Em seguida, você pode executar o seguinte comando para extrair o patch para únicas coisas no diretório a
assim:
$ 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
Outras dicas
Aqui está a minha solução rápida e suja Perl.
perl -ne '@a = split /^Index :/m, join "", <>; END { for(@a) {print "Index :", $_ if (m, yay/team,)}}' < foo.patch
Em resposta ao pedido do sigjuice nos comentários, vou postar minha solução script. Não é 100% à prova de bala, e eu provavelmente vou usar filterdiff
vez.
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()