[Patchew-devel] [PATCH 9/9] process Supersedes tags

Paolo Bonzini pbonzini at redhat.com
Thu Jan 16 15:09:09 UTC 2020


A Supersedes tags puts two series in the same topic, even if they
have different subjects.

For this to work, do not compare versions unless the stripped subject
is the same, and always treat already-obsolete series as older.

Suggested-by: Kevin Wolf <kwolf at redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
---
 api/models.py                               |  12 +++++-
 mods/tags.py                                |  44 +++++++++++++++-----
 tests/data/0031-supersedes-embedded.mbox.gz | Bin 0 -> 5342 bytes
 tests/data/0032-supersedes-separate.mbox.gz | Bin 0 -> 6268 bytes
 tests/test_tags.py                          |  18 ++++++++
 5 files changed, 63 insertions(+), 11 deletions(-)
 create mode 100644 tests/data/0031-supersedes-embedded.mbox.gz
 create mode 100644 tests/data/0032-supersedes-separate.mbox.gz

diff --git a/api/models.py b/api/models.py
index 6fd04fa..adceee4 100644
--- a/api/models.py
+++ b/api/models.py
@@ -562,6 +562,12 @@ class Topic(models.Model):
         "Message", on_delete=models.SET_NULL, null=True, related_name="+"
     )
 
+    def merge_with(self, superseded):
+        if self == superseded:
+            return
+        Message.objects.filter(topic=self).update(topic=superseded)
+        self.delete()
+
 
 class Message(models.Model):
     """ Patch email message """
@@ -647,7 +653,11 @@ class Message(models.Model):
 
             # If no --- line, tags go at the end as there's no better place
             for tag in sorted(tags):
-                if tag not in old_tags and not tag.startswith("Based-on"):
+                if (
+                    tag not in old_tags
+                    and not tag.startswith("Based-on")
+                    and not tag.startswith("Supersedes")
+                ):
                     yield tag
             if need_minusminusminus:
                 yield line
diff --git a/mods/tags.py b/mods/tags.py
index ec2cc49..2c3a503 100644
--- a/mods/tags.py
+++ b/mods/tags.py
@@ -17,6 +17,7 @@ import rest_framework
 
 REV_BY_PREFIX = "Reviewed-by:"
 BASED_ON_PREFIX = "Based-on:"
+SUPERSEDES_PREFIX = "Supersedes:"
 
 _default_config = """
 [default]
@@ -24,7 +25,7 @@ tags = Tested-by, Reported-by, Acked-by, Suggested-by
 
 """
 
-BUILT_IN_TAGS = [REV_BY_PREFIX, BASED_ON_PREFIX]
+BUILT_IN_TAGS = [REV_BY_PREFIX, BASED_ON_PREFIX, SUPERSEDES_PREFIX]
 
 
 class SeriesTagsModule(PatchewModule):
@@ -67,7 +68,7 @@ series cover letter, patch mail body and their replies.
 
     def update_tags(self, s):
         old = s.tags
-        new = self.look_for_tags(s)
+        new = self.look_for_tags(s, s)
         if set(old) != set(new):
             s.tags = list(set(new))
             s.save()
@@ -79,9 +80,16 @@ series cover letter, patch mail body and their replies.
             return
 
         def newer_than(m1, m2):
-            if m1.version > m2.version:
-                return m1.date >= m2.date
-            if m1.version < m2.version:
+            if m1 == m2:
+                return False
+            if m1.stripped_subject == m2.stripped_subject:
+                if m1.version > m2.version:
+                    return m1.date >= m2.date
+                if m1.version < m2.version:
+                    return False
+            if m2.is_obsolete and not m1.is_obsolete:
+                return True
+            if m1.is_obsolete and not m2.is_obsolete:
                 return False
             return m1.date > m2.date
 
@@ -129,21 +137,37 @@ series cover letter, patch mail body and their replies.
                 m.is_obsolete = True
                 m.save()
 
-    def parse_message_tags(self, m):
+    def process_supersedes(self, series, tag):
+        old = Message.objects.find_series_from_tag(tag, series.project)
+        if old:
+            # the newer_than test does not work when the subject changes
+            assert old.topic
+            series.topic = old.topic
+            if old.topic.latest == old:
+                old.topic.latest = series
+                old.topic.save()
+            old.is_obsolete = True
+            old.save()
+            series.topic.merge_with(old.topic)
+
+    def parse_message_tags(self, series, m):
         r = []
         for l in m.get_body().splitlines():
+            line = l.lower()
             for p in self.get_tag_prefixes():
-                if l.lower().startswith(p.lower()):
+                if line.startswith(p.lower()):
+                    if line.startswith("supersedes:"):
+                        self.process_supersedes(series, l)
                     r.append(l)
         return r
 
-    def look_for_tags(self, m):
+    def look_for_tags(self, series, m):
         # Incorporate tags from non-patch replies
-        r = self.parse_message_tags(m)
+        r = self.parse_message_tags(series, m)
         for x in m.get_replies():
             if x.is_patch:
                 continue
-            r += self.look_for_tags(x)
+            r += self.look_for_tags(series, x)
         return r
 
     def prepare_message_hook(self, request, message, detailed):
diff --git a/tests/data/0031-supersedes-embedded.mbox.gz b/tests/data/0031-supersedes-embedded.mbox.gz
new file mode 100644
index 0000000000000000000000000000000000000000..a32bfe494f6f3c5d961103d03bb402be937c024a
GIT binary patch
literal 5342
zcmV<46d~&$iwFp;VIW=r128Z%FfDU+aAk6HWn^V at EoE(DWn^S!WG-!DZ+HOgT3K`A
zNVa}%{fdmb4~>HoXk!s&stYiSZLl$mw~h)TB_&8k8(P?6e*8U|0)uSaQ&k=FFcVGK
zMoZ?&vwr7GS*^fxkn3rlvEeR=Z7oSa41VNQkmdMZ5Ru at Uk0aeAtDG0ixB<}#j4}9O
zzg0m#4nvgLdZy=K%g*VZQ$Yqjc9AzlGdHGlkU>Ig=HiHiND|asLClHea!xEE93r0t
zjul13Kp}Ar5}YC3wul??mS0T`{(^|RB(~=hehMmA7sQEqgTN(T^I}&gVRo-@^+ at 4w
zuIKLb_<~HBU$w0;3Um8wTrG}FSkKaNWO*(>AYp7rVFfws+_7C>xZjMq<y5C|4#%NC
zt^OyBN1+q>IV$g0jRZX%9Oz8Zj9-O21Q}My4nV$1Ff5c~(jm|$j;P{XZP4I{1lthx
zs`v%rY7k;RG_h1DenC-HER at Q{QmLrIJ$=b!(S at oh5228q!{TsHtKP_uiWo?)wjN(U
zs!BH7etA-Atq0*Y4mNt at 5?>64h0Au~aiMp$%iHCqKkAvP9mpL+yPRF#%^%BVLA)&1
z7p<%&7!PrMTJLWJZ`-;XJbB`CWOg5x3#~P3i{|hl9`#1|Ps*l#FJAY8g7W;(F0RSb
zwdX8~FZr^1Hz20t-85Tdnr|*@4|nrfR_Sa4ob9&8Rc3#Wgdv_0e#qh#2jrwPba0!E
z*Tl&0zQ3Tq@<ZBpX0_qD5l!#W#wV56lK{KnlmvX!)jh*<XO)ItxqzIhv>;BEE at Uh}
zjI~e?ER7_meJ_lXqe~<Ct_8XYm6 at D$i0vmwV>f)A*}LpD`Fj$Ckm;4ZxtAA}A<MoB
zEb&70s50_s0L`kORkG2l-4pYV{l}a6&0=2Yxc8CPeZIOXwk|vQQhtM13%5?jRTgr)
zVRh~H;^p!-pA8J5J9tv+POrI~ju(OGw&vMZ-JjnI&#j{J;Aq$VR#3RU(L0N1Ko(Dz
zcQ=J-wJy{fPJX4?;^=<a%Dcl&ukmsz--*xmMsB!|(J))~q-DLcR9}MYX~(=)`{r|_
zp^!ysbUz!ay_ay^+!Vw+q4k)(y=y!<cT!zZZ#QwL^)#vv6~z&kVJ!*yN5#+L{=a|#
zsd_(O#1<r+jlUf#|0{YA690A%bOERjm+#}qtf2Fs*YWFXAE_X^3`&7A%A`;KOu6m*
z8PYaygTwu{vLX`=d!zmkSq3^3T}hEexsWRq1w~a#rBb<EEJ8DB1=eRI3g`;E5EV&4
zf?AQ4N<l=tP!<G~=?_O|@3i!EY at 1MdDD!8fB7UzZYOz#4YAd3 at SNaU<Ve`f;rXr#7
zMVaQ>a*&c!g^375GpXM8OCAL&)Nae))Ngn}5ET2GFGk#NQ!hB#$xpaIl&A|76<kmd
zgtx|%+3YAn5EDVHC?%mHDliSaA%HvNf+C%9=*KNb?<_x&Zf9s`nR-Djla{x9dBGuS
z*}+k%Mt{;Y_$i(??Sg0)c6mZI1Km at WGSx#LJA9~P*M&;mTTuFW{cBYJ5-#w~=U>ua
zKCOQo^3=B=i1D`#FXkM}AvzA30xVjEoG7a~Q515bL_;O2MS)9FcRxKnD~aQKU$8I&
z?2WoZF(*_mI?c&oSew+E!wEFVNu%DF3_CRu^rh}O`0AHjb-(0GvtM$RblO#W3wdWP
zh`GbcDD%-BF2NsBmH>d{oC5fh8HdoM5qN-M5hVhfw8xpJniP(}AdUvei7+pUMSj+}
z<wrA- at 7>&*c4;jxaVvPL@#2S;NFUTA>l3;c_$e#ErPP3O4h|SN`hjQAlbmm^rL<X)
z3y>9JPLjXVP{n(rmT)PtK(~C81gO?*Ty%JdFa(%~;Gzs1<lz at -RurDm$v57PxFeke
zku{|)m4Ig!F$tl)CCT)$^C_K~TI;hT$1xn2%8<FDP^vW=g)iI*7nPWcN+=820;oM6
zHQu3iNOT}`5Fgs-QN~;PE{lYu2s!M8$4+5Bk&EDzVh(P9Pt-o`=@TkbjT<#+38LCi
zS|95x7E}6OTwnH%S?BTxS?56;SSqaUy(<Z#DwIU^h`1LDA`CIB)E^c0Cm_DP;UljS
z?nvMM+n}_Q{c&~#(K3z?IRum7N7v~OU6Wt#7-i~2-*MZB65Z4Zhh9(jyqD~G?}v9l
z{hwx}NUP3X;$~6Yinq$*D!7*PpgkTuD9W}iJSa^^y<IAsr+Z>&b=7Og(zc-t1|(=^
z>!eYXU!u0zxw`AF04GQ0izmq2t}GNDhW(Y=x3#v}zP^4O*R_kwvU)46=c_=s9bD65
zv%gddHy2uc?oS7u(QVlnce4+xG3L<Y#%i{VqM<J4-Rp4NBX`4KE7tJl8Mp7AW>t<6
zesmQ>!rblf at ibC$bc=ox6S+N)M}PLm-7XS at yj1><de$spG#B}?ZKH$=gdE#uoJiDi
zMW+275>*83dEG2PQJvEP0(26wBuio;Czp!_UgS?Inc8t6=oj20KTP^4U*A*^y?;Tb
z7=TC0l@$cq9Z(6z_8PE(u>eFW=p*2yqxQHmq<wk_r3&K(F16P}5m`rh-v)9H<z(U@
zBvExdYVl?6<82sP#2%m*?+0KT)@%Zc86*Pd!bRw0)S>Q-4>y2u5Vkk{vVz(-<9ye0
z<26_(<<`8MTcbZ`#3g~He+LAf#@p at YI|zM!tdhk4O}mBxbwb<`U@`e9=->r_dk1LD
ztGl6LQ7`rb5N<#r!CXqqxc#>Am}lmW$@#mDBRV%DX!@0WKH+tT!FeZHHShT}x5E5E
z<k!y}I;Xb*EshB7t|uJn{>Kh`s_|jTof7*^?O!N>lOcICa_r;Pxx+sBgc{%8*~_-f
zKdCU#Cx176_%qI;H!OGR{Vi`D`KqB;P!~h<fc|@LEiLHT=k}5v9GBx~)PU0102H_z
z92n?acao!T&Jr}j$sme$u(1kJ2X at EkJTl=cC51!PKUn4bvH0TxyB4vllF+Y8P57#l
z0IFzKZOGM{`bQO=Ysm%jMncnwVO<Y(ur{X~s&ir{M`?Y300==?A4)PnJ-h(|Y@>6Z
zp28NIoqn?|7Y7~-^k+1TDA=F}0$bzraP at 5k2QG=WIfGC^S2zR&dZ2K0{sPA<I7%z@
zsb>Lr5E~71XcSt(+;Trb+}`NTp-&e<4qf0SFoK#5E4D2gJQ2ZIW0oAI<+70Dz&Q#u
zNMTofUq8OOliId4s_VHy&%VvrS<VPNUn4lkSw;@W=}7gUQ23f_1W9ZlR$WLK9Md4t
z=LHyUk(|x0z4b5lY!B5vcWb#8_*YAg(iZGo3kfiz=@+t7jk-Tx=Pb?H3mZ at eLh^Ok
z0}p0H00|bYEW at x#4x;guYX*TAgnYWi{pePh+da-gpYC4ge)_ei6p#F~XL=M^c}miN
zP|{~AnGSnEg2FvzLxx8}<a!YT_G3*qXB-Du4Z9ZG_EwZsgT+t+A<Tevf&Mr^M$uF*
z<C3Te;<PNQdPyr52rkKnVHAXtD#*H~DrJ=z#VS|fID~rCvB0Pu=tz_w>2oSsgW}Rn
z^m}qW%md&oVr=9iJPY%*(erSXH7STM9}>qhtDKiy5mW)13oreSpsG9s05GE>Gqk_+
zg2)3O5ao(UAB-e?73{)bEnb2bXg7p;C;~&<U=0vTFSH^r*dQD+h4&~p1AZK9H2nD&
zDCd0*GwjR3O~iC{_Vk2jTC+bp at Z&hT|J!&mP){@^5UN*)#y-8K>m{LVNQx*LGBG5q
zDOi!px~dknQmL$$^b%G|SWuW+*tY;J$00$o1lt!>>t8m|<ptYgzA6Ehfjelh;7-aR
zW$F;I3=XMsB6A7H|IH8ghMK*a&BNXWG78(siEY?a8KB at Atj@ex*o=X(Iphom1$3)r
zTQsNG!zmwA*JKznu=|i3OM+rxUBCkj1hFGF8$hx9?8GwDWEnt5dKbzhpaQ_>P at w_!
z4d55bgt`|+biji4vm at taD8HdMd~XHgchc;nLDB0+eokb=1|xzYn>g6e`?d#X-ZZ7h
z-*+=tv&kCT- at tR`9?FPkuoXe|c!vH at EK91SNKlypkR_^Ej^mQnMsX^j3>4LIpm|%o
zpBP|(w8{t0h1n<Ze?R%v0TnbjL=PNm8RRI493Y{kqgqTM_5IXg>{9?kciqe3=x~GM
zT2LK9Y at wk?>-pWhmbHepcE-};Cm^5yI<-9<(aqUz4~KLd&&-I at S{-bdaoiQlJJcW$
zV<{~)zssEp4H|MGkNqe>SO=U98BWkA-7e$HuW1&U&}@wGV=)G#Mc{3~txgR5{jbG=
z81yQVOEZUzoYt11Vg=O<<0uzj)uP3ha##<~2?{CFN6_%liXy)IJNODixvl~$BAGL)
z6>LHX&09kI*NOE&o4_+-fR!n9AV!!eekFwk031+rd<>~YDGXTghSa at v`c5n`grbso
ztaUpWb(jSR3JZogG*x4YW^|ti9SayBjC8HgOvDhxe}%E&rI>aSw)3`<G<riBP(m0E
z2^B*A$6)bYvp1ex4kxwlW&5Ui!Ep&8dyL=ty at Fu3XSoF3_lBd|s5!a3f$y6J99&Fl
zH&5xY4Tkb)h?itY^>2dvHn}}CPoTC~<Dx;9rAhQF;LdSFiej)7u{{&N^Kb=W$dM2<
zSUMBt#K{f at CrRaJ&eFqA4owiVLTihz9PttCSP`)S_uPo(Z8Cy+9mpwqq7*b!ep6!5
zVI$r1HxzYP7CFR$Z7f=uP>>WqLbN4;$FKvz(oC|GZ1g7)2L2FD=)Fm3ZOI3cSC~>0
zaF;=#V?$m*y(L9O6CBRzun*?yz^iCGrwb)YxUmDUM{^v+QEUUcz_fymI7BeP%nzhd
z%b>m{%p{Ny1pvZc!Z at Z@5T;i8Kn8IcPl22^JO_CJrESOh;UKV<*#7I;uYNG%q(FBA
zPUDtt6F{D%2jgkP`k!qlg{{v?bb1ygkF=Eb81!~2?g?5Wy7nS(c_K$Cpi{R5goj!O
zc0}|!#UXlaSLHkfe20-ypr1){9P|L3sGuikcLx2Jq~#eFg|-cIJC#BIrD=Pf4+Ki1
zR=7r(H?%n9mk!JHoQ~M%U+^oVEYBh6wEF()yAK_vuwmv3Ht-J6R at kcHzzS1S=rCzN
zj6T)LFMz<mlX_Sbh8b1}xwXkd6DXCH;?dxgG)vN%#P=$uhq-<n9kiRUb2cZnC;*V2
zr`R*0&IR_MA4 at Ckhf&1LJ9sUM;yS%>N*Zi|@`M0<1Hb%>VZLtB-xE$wnE=fpANtr2
zPWtV27)7Lj#$v*bKJr`SJM?z~+}*~&_S2Rox<RJdu|e`j=|yJ15J9SWB<=mMeKMI$
znp8kp_#BO-JBB<^v6u}xtShT*B>iy5#kD_5DOr;CgZI4f<P`JRE)k^!GwS!&mtt9b
z)#Cl<z(SAYB)#Ho$`=oE-cF#~KEeZ8cYz-t)Ki&1-}#X}Zr at cDHC%Y39|w#h*24Uo
z8h#&lN+*tYX!QJbGz?QqCoF%RNB_RXiNs^?G<yHx(9- at 8M%d!8DWhviC5p3vxyjbh
z_>77L>CjfgO!n+E5~VUUBAX;vc($piN&+Y4Bqb-pR<8BW+i?H94fi8&!>Otwl!YIE
z8?HWhG`#$#GrU)f?VR|AxWx~5>yg(ti(;phA74CatC!VwxEjf|@PSOri~DD at FJIT7
ze(sH1a%VNV>-+xIeC0b0t2=n?NQ-AbQhZ+-WpCW;sSuQ6zqZxAx)2y;rB%R6*_;nI
zg{RpdJFKm|ZhiY)v<7_xFT9~Pl9cUeb=wyo?YS=bb6IXkbLDB;{LjA)xA)zD*V}N;
z)%Ep5Qyg!5vC^LUO(!p^SL3{!?JsNbO-pO_nlI&-XQ`B(C2zy^yDMSt-wtZzrCYZA
z+q&uI2QRn6TwXL+=99LKJ8EM-9zBHR8?!Iv+vBZUUuI|Ptk9Q>YN1xjZ;XDgcYpQb
zPoJFfli0-Wh1k|Q at oc*34qobQ at u4?s4p#S}YLHQn=vQsGUwhD=dtUGQS%>+Lw?S8K
zUlsD^H8d^Hy%3g{v2=aY?oDTUaQ)JpiS1Ap{&^ejfBtQ_r09x8xvYvgK`e>oLP=5z
zsw{s&qnJQ%RE}PT6Dv}=A_zbAGMrox1m*wRx0l_tfhY{Xd!E9}N|lot&&@-X1&IkD
zz at dao%WizdU_f9<0#DyDG!-g=f?Fs8uULW39M9#q{c&CxZc=L2V at E`yK-HgiVYtl}
z;H<{7Bsqp73}A9J3^yq~PnXQEFjiabokHrvq0y|2*Z&d2$@-(Xep-Mk%q6P-FEAXt
z(IC7*aAo0$ylUiZEu8GsWZ9`lUv1PAbqb!Lg<~r32aOrfHPg_1O|R&E*KXzgSi)@?
z2fS(t2LU#q+>H&Uf608%BED=<G6^Ra#4ZU3SRx5WjRymACUfG}dI3A7gyS4>{W2un
zVQEyc?%bKv?pog;`UWFf*@L%D)*JLp2P0=V^I6IKcB|LWs8eZpZ84wsnluO5YvZXn
zo7+CkbEm_~V4P7(+;wwhx%W3;SZKdFR at dnGt^3e40ykGHFN!s7TKin9<EjVeY=XkC
z at ngs4^p(~kQ&bmKLHdhsMtKZHJ7D$OQIU5^fiz7vS`545x#D>D<{*DG3CFidIOUUE
z9;2b7OyhTuD;BpgYax*5W)|&YaTsuo0=aS+g(qNf+jh~*WO3^UcdFu26?dH~ZeN6U
zLKn9m)H|MvJE3&T947Gg at NRqJx$9tY$kqiVjBuS;kP^+p#PS4Xz#?uO=NyVP+Y{g*
z7T2H1s2HwP+$^%xpJz2%b7ps$Xu4IxA(;YV_(j-xOE~NbPgq1JHsDa+D_KOi6hQ<$
zOg$G<VROiBB$j3USrV;v0LR$}vMkhA*++Ijeo0Pfd5A`b{VCvRU`~}?hy%ML#}O<I
zmF!Rq*oN|sM})z`T|Ko at 29dA4h)J-_E-5TaVOermhF8_T|9I*5srGA{rTQ$@XQ at 6*
w^;xRVQhk={vs9nGhsS at V&(LM-vvK^fY0%DCpP@~C#&_$pA0CG-28>Mr0Du)FivR!s

literal 0
HcmV?d00001

diff --git a/tests/data/0032-supersedes-separate.mbox.gz b/tests/data/0032-supersedes-separate.mbox.gz
new file mode 100644
index 0000000000000000000000000000000000000000..3cfc5ffa5625fee1cfac15b598c7904d757151eb
GIT binary patch
literal 6268
zcmV-?7=z~@iwFo_av)v+128Z%F)ed-aAk6HWn^V at EpugXVRB(~WiD-EZ+HOgT4`6}
z*t-6F at +<c0FRjZ8WG11CzKwuPq97n at uUf8<Y)B*%*$EKV`SIu72`DJoW%cRXeft(=
zNrpYV^ROQ;Lf=K6KlaUpsba at o;1HYaz%L@(4g4^|;je)n85UmV{BX+LU<1P#lkIme
ziYU+tK__e9@?G6_a)$2~kx8#T<WJDli|HI>Vq#A{J;DSDoR*XM9IvW5zJPRs0vx(_
z6k!t)?3p+`MTTQzFJkSWv^V%O!rlTqet_8tkX)K$H)c%?kJzyvdj=+FTY^hF1pn&!
z-iD6P$b$JL$0iZUZJ#maII>_r+t4H1_t+auVkaU+<gRkNe0^sAWzKB3G=Y1#Cc&ii
zXE2Y58wEMK-uE&Ibh>(Iq=cRXC3u68X_NE<*0-<@8|Bi~LD7~TQNo$>O at -}a-2tta
z_|Hf$g+ynGr3<q18AT;tE=ZbK&}4XLEYh{;Mx{LoA(Gz1=J0M at x@Zia?wTW~)?aZg
zJx-R__ew0Z`or70E#DAvy>OPCQfb~Bt0<J)-NYqa_d4G at _pHiQQ%~08P=4 at 5Ub?AC
zi;>v4>DlXgztMZTF at zhZwKM{`JdeF$KC0ixd0bxKkMKoV=ypx16{^u#jpq2a6U;94
z at TxzkOj`z5aN2e#5d{<3mW`+7u$)g!SCUF8{~b(-KE-T5)mI$igTgRCY>vLdW`6Vi
z8NDZmec4&1itk0#ya!2ui_bTq?vV)&*_vngrtM9O6{A=Mn<-v^o{E=Xv1~sc6C<?8
zIJ at ooB+9OuX7*hU4GTOoyJ=u2$gYMSd7jy6c53V`4hdL#am#MATI{FRSA;E|un`pp
zK2 at Mqy07uesVgeOr*qFJjLz(65<eC6__lo|o!Mv7xnfjT_Jeg6lTxbkr^-~m8pZOW
z(7RF1&Ux&$8>3FxF-d-A-`BcUrKwiM;Hf2adS1(}S-Mg#G#u<NqKCLCi^2W!fz#G<
z12>$iG4EEAcw)v2(~7--6NS5Wp1*M(nyq_oVAa}vk{>MRH;G+~NK&&_vW1@}SC<PV
z8T14k+TG6mpdseZnq;28CyFzyHuG-n&VM)$?|PZak2!y;_kThJ*z at -<#0h?Var$4-
z+xYO_aESfj6&~BwBddtMe4Mghp0h_0(H+oUC`Kpyx4-QP>+2~RC$Ck){A+1P7V38f
z-9EBS^x|rQ#*4g?(_}>|a4Ih=g2I9G4y^bS5>#~MFF+T(hB%=p$wiq*ET?iDI_dTY
zr*EkA4c)Q8-_Xf##UlT;D8VkuPBP(xEzzgo1<5P6QW7!MDmtmHY!^v6jeF!_=*eD2
z`!0#XDwJ<qZ!}|;<2bqIv&{nYuZbTX%- at GZAX5=Y5{N+NxYx|%>2ya!pc9S<{<$JA
z2}Kd4!F>hkDXM(Rpl|0Kz2^LtrJbS;Qx_s-O6;m^uf`zC)QgPvGW$WUD5ZzFs^YP&
zdn~3z0oi*@rc{$acUfZSo(HbECBE<>(s at d{(o9(O;=4#cqL7%dRHCp at TB{{2pL1;&
z8#+k|NOdIVcu~voJeT7IP>`r8T!G09b~}B4R;InTVn~$-A#QNl=W|@K+NeF=^vjRs
zTK^G};bY~z^4M>b`JyOL$-Ic^o267+r&3Zxb};=eDT#-rv}KNUR~(;v*%_T2d&6V_
zhZhBiIATtMfO9e=kc$y8p9UYA?~{FDr$VaH_yY_vR5xy<vx26wjcJ3G*0p6Pt{eSC
zZ7Hof?vz>nC?}$Fn3FUe7=9S+abbHY1BD!1q|q=4eUskg0&6Agvjt`V2Epe9;Vacr
zyk%+uk1`GnJFsww%C$<h!Gdx at w=C!toxnvN{-d!SkyASP%HP!I$iQJ_PiW at EAeniL
z31qR%j*bhTRxJ~Ib-E+CG;j-?Sgk>z7iEF}%)Av5&!r-g(HU3^gz4d+ at +M51p$%cq
z#(Nva-puotUMd7p%!x{lms2qSnTI8NfJ91R?OYTU9-^OEF1$k_w?|>M-R$g^lZ$UG
zCtv7+tw?DrPr4CT;I*BKT+t{sR*6cWnEncJ;3RD17s;lY+kTt0o=ktao665NcP|+P
zli<fN=nvhKU2ICly&Gdwv_`ao-MeAX^X;~v#oL1R=o=va!=)w~m&V%oI;olsE3SBb
zN5fGy(5JWa3x9a6bmmrX;oy7EOxkMaTD+QE>X%AT9yQG&={QbPzZzcp-i^>@ka*pb
zJVn%}$@r-@>0Axh0-3GkY2-$Nc;`Cm?EGQAXezTx{jMBqgNHk_GE8dv1vba=QyWhc
zbvi0DD0w0?t7=Jw{%!kGJ5z<#@RA=@hOM#5HQIiONh^8O$KllW(IrI2^_!^3(60Mn
z{A0GIIr^<z9#k4=AtNp?eMMs^PG&H=i1dXIW~v+W*bb?Kmu)|7FIEvPU}h*<+6G2?
z#6X4m2)?qwk7M1K#R1YilRn!nwRy~>{l@`A=c%C!)D^)UnCC76-0%w>!1IF2a}rcw
zIYH(GPGNcWHJ^KZ2!hPQ+_C*E*|O(J5z+TmJkfy-A*V{n_s~lagRz|ov^6%woFY0F
zXX&VI80ynx-Um;I at f@?)fgviOeBeOI4!&sVA;D2;*k{ZAO0&rv at 6XUY_95P}0mwSi
z#}0=5OdNrV;2|hCgoeVKvLu112x@<oT#KlFHOybyUc3SZh1`l2b1U at Q6noIN7+)b~
zPvZ4D`3j3ZpSNW8^D4K)fOCw!0Yq<n%yd8ykRV(rcb+8<DK007OgDtZO>jh*ODi{K
z+fVM6qPgAr{Y^)SzE}}d2*rFpEB#&u=iO}AydTisisWCG{N)pazR=eYZFXwjO%~aq
z{eL#Gs}#R%xglcP?Y={Ro(;)ck?ZX4&b&0x2gvyK4ZmqG{Xv4E)(SS$`yUY&ePMeO
z{|`xPM^+W1h}w7o4e7{tCg{s-317Ru`04$S1bcV%a269(4&8AWgE@!ji=JNZFO!m%
z#*iJ7(&;O7gY5{`c0>BT7YS-%=!b;e4}9O+{V<zz3-nX(dG1f&*O=b1571XqM`3Bw
zhLVCd&nJzv9Y$oE!XZvV7w`EIf^29{l2e9x6-`f0H!&E-MHYS&hW$zU7=jUu2z-x5
z6Xu-0s?t@$egt7R2VvJH$j-LX5fpb2VxZi#u!rpEXM&(3b)Yk$8K0TE!7CCzp>Z6c
z-Di&h)CGEoDR~a at _i3cNGh+<ZH%=F(>BEjF5f~BO#V`mS5oGB>fIX5`MsG95$tgoq
z$*ZR?JLecCWh>PIA|OE6-v#S~ueVanHaW-wb2wvdCmki=Q=0041JER4fb-;M;Mn(^
z1Wj>71NN?5LGEd>q8l`RWu?t3+Nfr!C!gpFAqHjWh?dk2)vAdpdsf=XjD5J+U1H<1
zBqam1#()ce)0^ZIJqjZ6bea~?G+Vs*EJ$sHGo?lPEY$@;en9Ox_UtHus%^s(T4KtN
z<$Hcw0c3WTQq83LCU!~&!LVs$8zdzNtRUTSY=(=+C`=w913v1u|G1e-X=C<id-iA`
zjb&M;VnL#YW^Y<#n1u{gAd8xw;lv;dD5O(S*pMtqgm{TZz*c4eLJploFm*;=Ry?JX
z%am6-b303wQ;7*sef<9Hj=#VN)3A~m0 at 5cmW^K4ZJA$AUH`WRML`Aryrtd)qhZ%&>
z)Q3m#Gp13%2VbK5Z-&D+@#7G}$}tkUA*}$M<avhgm|JmD4yeOE8>wqkTKATs6l_*w
z7E&ruD0e1F#yWTl&q^spGFzZjW~CqP0AqtHejNHU8Yp1H(01u+ghrL4^lr7KAJEs!
zoEMX%WQi$RH+boXv((a-mha$w-;Odh(ziAtF{Z`?Vj#X_n`wOnX6;b&HU$&BqT-?B
zciqMXuX2vjA*6IPsLdZWVF(Nd)W5ZU7b-kLsdy`#T*hOj#2t5nGWu9_wLNeX-K23o
zRSOO8uy%;qm(twM7T5`S4vk*N)C2hg5<~P7W-=jzdVLzBmOi^H^<3(c%wASMkxoHO
zJIw-BOIFE(X(Y}@KdJN&@wGQMPEGN3(#g6A`heX$*i|8oiR8#CufjFj%^?TYqS8FD
zp7pI3u%~tAd4-&TUVr|LL|H;-Z$9kX5A at D7uxC|U<~$@%y@$q*f5Tb=Iy*c at m49~(
zje8kA2o=!T;mu&s^Fk_JNCqW4pi(1^&gLh?YXY at SdTaxZc5(*kkXLyGzJ;?V>?w`s
zCFm-kClR43qo0c(@bC|K_#5D1RnjC*5WgKBwl#s2<MZ~NbUhZ%yO#@a+relMG?vqb
z at zk*l-fZPn=hD4j-1NFvournC{L|pt at 7FJD>O*pG-o!y;JUo*}6>B<jT8UG;<u4YH
z%Vw2|>n-wKb2u(ED;LAb6_yfmcHMWQ;nKU(d-i!tZ>$>fQ}-$v&W7#sWjP7L-nh5o
z?5AnxTD&_amumqp+ at 92rn}0Su{4BfwTkvpX%6x4+;JHYhPkIeIXz}+(y~Wk}^KNHY
zSg-EP at u<GmLto9{VY`4^`H^fE)@@gI#&|Jv3yn!rR;z`6vs;z4=53wxMmS!ORr74L
zusY<SdZw%#h09+QY8M4E5{2+aDxX!mt9kwQcCJq^qqvsmyLWp2dbaAug8r}|ohy<g
z^}vpZbzSD%A!l4Hu^yQYPKdXh+Qae97%Z-pjN*&#yp>>eG0E%k6}LK{>77C4{6_r&
z5C1da;f<?FnktDoP1YohR}@td3kqm-MAM{-TF?gwoWLPYDT-nSF?|3WmQ-2&dx672
z<vNAggbraFckhA2sRX!P5ooCh_&)#+bK0K*4hNO1I%SHRw%L~YE_Qg3E50bpe-Stg
zq*qh0-VLBm`YzIsz at CTE-B*~flKu&U#wo8L;UkFhUxW=m3(4`>R^z*bbi``^QfydM
zICkduEVn(@J3%|RepqXSw1Z`j<&Sc5?9Uk9#fHU?V8gulx5b7<MX5?W1mLPv`^;n_
z+Ktk at l!{3CZ(ze*;d`)QSx}Xl!kyQI<MfHz{~|IBSx(e=?jL~+f2_(x<5JxZlIftk
zu5+<DRH7&{s;l$S$i!27)f5-&a-B3L*Mc*cL_)9MNxGfJ)m437nB2E|jn>>7UEH)+
za|S7AiWA1-M1GQ2fzhw5h<XDyD2#l&5j4P)gh6vO9A4kYNrzaR<n<KuE~?MWi+D8G
zfVikF_)7+v*7>SZkT~ah$@~4MyOAsFo#|>ly%p>Cz0Q9f8CDRNS9g)&3wyN-Ls+_J
zrbqlVqAv8%_G9uqnnBqq3)#TGZ>?EQt(iLv|I!M8Q+Y|`MX1UIP2;pb3jY?gUHF$5
z_u=1Tq4fU&{HyRk(BB{E?;k~fkHNO at qr%?^3jYrJ`w6vt%R_z0!syErfv<lUHvAUu
zv@@uM&=Yw2dnW{Mj^JssrwxDPGdn at swFwvqL|S at oeK2yfwr59nI&~Ama}3jrHgK<L
zlI+wtof|>JinqfuR2i?Z5!1>31_A&|V$Y-S1w4W1- at G1JAw@P`s5*rIDH~kK%W&g;
zL at 32m%BG2aN~z9gr~6QnfQMCm at 8@WXOFy61FD=^v$%cLqq>!c`{ItJDn&HZuSvvxw
zY}jFx(DKyP12h3;r|ce at pPgKwaSB<bM5hSeGZhpx_4I&P6pbH)wY)5{Ie#yr0R_yS
zbE`kuA!dV^6CXtKl4#LZ0Y4ptwqS#c6s6h178 at wh%fQWJc-Rm8^#}g?1AqOy;jiis
z{PiIIx>@1762ac~AISiF6F(gKVfOdN{O8_^dBgS&{7eyC8L|6gUcu9Jj7U-5_u*@e
zKLB4J0I>gt at b#fFD!*AskO~JGgU_*<&#TKvR-cAG7<xt~Psi}wYXn_VrMC!rVIM(9
z1{6sVPJ<>a!4+ir2t{v(Dw6aL at o%vC<H&q4_PsTfgTGGoARxO3elN#jkP4t#7m7Mx
zC~BNilrYB^x$GZ$hE3?{)|xj+plYHhY65<WKQmhcOaC;SSN8A{4yLPnc*z}G_kD<(
zY at ePn_tVS`{@T4;+|QHSs;ha0D(7lf*7ag}-?nr-zvFdxd8YXJr?Gh%-*?vpUr+5;
zr%-L``G+<h^|3g*il!@9t92X0{!W{`!<Qfz$CxvU#eHrpUT{M};(1lnlJP7jPzXsb
zXmBq8)r$C0{(c`C->kg at jc<1_OVd;~TU;1=R#xEn|1 at uIy{T$J0Dj*66+Z69ROJrM
z(H!c9q9S;=COao02#A1kQSjFv7G4mmtx6wuQj-Q}jl-;Atzo`dc!7lQSV}B at 2m;$-
zFmKQ>6+_`|=R at NbTYoG=^E#PTIvcgnV7*4&LlMGQRBXYkYa4~EE@*u{60;)FI4aAS
z)%gd6>jB at MIl)xJ)@x>?X0sz{F10ol+S2oz=4$Q^`3YMkYBLd*RrMoaIjz~$bZau4
z)1(?}>n_XOCTp>7i=WltKG#uMtJZ=cAq#IQT-z?I)Jkg%3;`DyvhiW~YiwOzzyXEn
z*m~k`l=_N`wKdgIxjR}KDA(^u1mrBnKGl*S!@&Y-0QXr8hI?vr8~EczT^i}M*>wY9
z=Hi?<nlu}73s${ltZk at lWmc$7>#bUQ?v`hiVl491h!`4DXJPkxjah|2Xfw;OHmUQ9
zLZDt%*=`#1>07<0t at u3N_G4}DzDO5ScLLlp-)iwt5|uP(Y3;J5>t)i{FlV-3LVHX%
zw)RysUyk+OM3L5(!@;2H<D8aw52fHxI;s_eYVe6R>A1eQ)=6Nh#TwGh3yl`fW4N$#
zoUP+;*Nd(vVYN42(7iq at t&FmSu^lt2&K at IrMUUOKl7;fdJGWx#DL&*jE!Q2ara at gE
z!&P6CoJu}RzQ1K*+9Fu9Ge-EOWb`fE_dSFSkl4Cbp^8euQq=>qjd0<HTUa}KU9@?a
z@~19G4a~u&z)i|Vm8FIj-4);0p2PA3ADO^|RV6=uA1JXli_t8uipy|bUe@(;KOiT{
zq*=)``K at 8F3$4w-+vWnTRNjag&-oBDCf+K%PYgM7Y&G7bZI7^GZ8o{qyQDHu>XHOi
zoa(Sgi<-up8&|_e^&Zk+HU~XMfQ4~Qq%6DN<X4q;{-dpw>ov*77{#6~Vr`u<<9#e`
zJrHYDK`n>Lr7~hnhgVc&%5<x9<IOCSbDymfB0{STQpP62%-6cz#y}V30p3$FEY`+P
zRi$`aqr*wq9>&KF4)K at A_J;F~2c%OoP4Pglak7R9x*VbxC3CU>Ws30S&Urp-ayTzr
zopl;~s%qUzMGx2E#PwX}oR&Vvfg2>fan7oyu%kf*l*B0l2}C<ofabu~kt>9|44x~5
zf8qbcQ6G5M`{(L*T{_DB-aoxX09*fq_fW0~m|XRx)1?8JgJAN7DRThM9k5(6yp|6?
z&-ZR>m)iJ#ewx2(uKVjE?(ad!5Cp$e=mOM7F_xE&^%UtFI?1Ej=6Jj~F~L+c!H*m-
z#=k|#Cj=S)1G-jH5aeIq6XahH5o8R3YgCwEV;EH4b-#S^%w6yxguG(Z?#SaM!u%~R
zj at oe0GL8^f876DD{=$`{{(4j{08z@#Y;ZI~wEWC(YrQnXa3Nk$GB+`tPZI}_H$>!6
z^3Tq-H&gG(tz{TRYv7J5=T5!JooMoA<I|=ISu~PG_PB9J!M;Qqx1iFFoDP>heSW1s
zX_q{JPzZ+*j0)e at m@0)5g at 4bc2W(TvR4ffVWx>h`Qay0zH|yzxtdRy;<7<ZVTsI#+
z!r|H!K9vQCdI86FvFAIuES}`D*Vd=&T=wJ(-qsW?%&aZ at HFFZ}-;>*Lft)x~O}mTS
z9%L&g$#%FwgtH|-J<&#{K!V*nibl`a@$WDw+$14WWM`_{nk>rZ>r*L{68w}hsnJgf
z)Cx+O9|1t6%vT7g>n+1*l%;(X-*y5#)CuZNrOXLD+M5gzQYrHlM2fymjgii at JOGj|
zX?Or7#cCdgNhOdUeTkEzAGseW9p(hv&&lIpX?K^8qortkdbkvMDg|DO%t#HGA}bCW
z_bx{FE>44*BE4V0ro<fHj++i9BF85)J$8yreHc6)EQ0qIr3X-vJ(m#F{*Kc^s7U|A
z7%DR2UJ$ikV|T9l45WZXk0Yt%=*OYdH9hxYsmQ+<bv}lsjyfKLQ%Mu<!c)ni_X8?0
zJ~g7+N6jsu>P+eisw!oE3RZ=hZopMnq|SiVWvNfd>Z(`*T3wO430qwqn*djrrOwe+
mDD at b;3J2bfuRaTZ1F-fXwZmAY%pPP#SN{j-!1$7dSO5UxPbkm;

literal 0
HcmV?d00001

diff --git a/tests/test_tags.py b/tests/test_tags.py
index 38ded37..73f0c18 100755
--- a/tests/test_tags.py
+++ b/tests/test_tags.py
@@ -127,6 +127,24 @@ class ImportTest(PatchewTestCase):
             "20160628014747.20971-3-famz at redhat.com",
         )
 
+    def test_supersedes_embedded(self):
+        self.cli_login()
+        self.cli_import("0031-supersedes-embedded.mbox.gz")
+        self.cli_logout()
+        self.do_test_obsoleted_by(
+            "20200110173215.3865-1-quintela at redhat.com",
+            "20200114092606.1761-1-quintela at redhat.com",
+        )
+
+    def test_supersedes_separate(self):
+        self.cli_login()
+        self.cli_import("0032-supersedes-separate.mbox.gz")
+        self.cli_logout()
+        self.do_test_obsoleted_by(
+            "20191128104129.250206-1-slp at redhat.com",
+            "20200108143138.129909-1-slp at redhat.com",
+        )
+
 
 if __name__ == "__main__":
     main()
-- 
2.21.0




More information about the Patchew-devel mailing list