Ë EÙŒì(ïãóÊ—ddlZddlZddlmZddlmZmZddlmZ m Z Gd„d«Z d„Z d „Zd*d „Zd „Zd „Zd „Zd„Zd„Zd+d„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zedd«Zedd«Zedd«Z edd«Z!edd«Z"edd«Z#edd«Z$ed d«Z%edd«Z&ejNd!«Z(ejNd"«Z)d#„Z*d$„Z+d%„Z,d&„Z-d'„Z.d(Z/d)„Z0y),éNé)Únullrev)ÚerrorÚutil)ÚflagutilÚsidedatacóŒ—eZdZdZ dd„Zd„Zed„«Zejd„«Z d„Z d„Z ejd „«Z d „Zd „Zejd „«Zd „Zd„Zejd„«Zd„Zd„Zejd„«Zd„Zd„Zejd„«Zd„Zd„Zejd„«Zd„Zd„Zy)Ú ChangingFilesazA class recording the changes made to files by a changeset Actions performed on files are gathered into 3 sets: - added: files actively added in the changeset. - merged: files whose history got merged - removed: files removed in the revision - salvaged: files that might have been deleted by a merge but were not - touched: files affected by the merge and copies information is held by 2 mappings - copied_from_p1: {"": ""} mapping for copies - copied_from_p2: {"": ""} mapping for copies See their inline help for details. Ncó—t|€dn|«|_t|€dn|«|_t|€dn|«|_t|€dn|«|_t|€dn|«|_|jj |j«|jj |j«|jj |j«t|€dn|«|_t|€ d«|_ y|«|_ y)N©) ÚsetÚ_addedÚ_mergedÚ_removedÚ_touchedÚ _salvagedÚupdateÚdictÚ _p1_copiesÚ _p2_copies)ÚselfÚtouchedÚaddedÚremovedÚmergedÚsalvagedÚ p1_copiesÚ p2_copiess ú6usr/lib/python3.12/site-packages/mercurial/metadata.pyÚ__init__zChangingFiles.__init__,s΀ô   ™"°5Ó9ˆŒ Ü  ™2°VÓ<ˆŒ Ü ' /™B°wÓ?ˆŒ Ü ' /™B°wÓ?ˆŒ Ü 8Ð#3™R¸ÓBˆŒØ � ‰ ×јTŸ[™[Ô)Ø � ‰ ×јTŸ\™\Ô*Ø � ‰ ×јTŸ]™]Ô+Ü YÐ%6™r¸IÓFˆŒÜ YÐ%6˜rÓFˆ�¸IÓFˆ�ócóx—|j|jk(xr |j|jk(xr…|j|jk(xrj|j|jk(xrO|j|jk(xr4|j |j k(xr|j |j k(S©N)rrrrrÚcopied_from_p1Úcopied_from_p2)rÚothers rÚ__eq__zChangingFiles.__eq__As¥€à �J‰J˜%Ÿ+™+Ñ %ò <Ø— ‘ ˜uŸ|™|Ñ+ò <à— ‘  § ¡ Ñ-ò <ð— ‘  §¡Ñ/ò <ð— ‘  § ¡ Ñ-ò  <ð ×#Ñ# u×';Ñ';Ñ;ò  <ð ×#Ñ# u×';Ñ';Ñ;ð r!cóœ—t|jxs6|jxs(|jxs|jxs |j «Sr#)Úboolrrrr$r%©rs rÚhas_copies_infozChangingFiles.has_copies_infoLsN€äØ �L‰Lò #Ø�{‰{ò #à�}‰}ò #ð×"Ñ"ò #ð×"Ñ"ó  ð r!có,—t|j«S)aKfiles actively added in the changeset Any file present in that revision that was absent in all the changeset's parents. In case of merge, this means a file absent in one of the parents but existing in the other will *not* be contained in this set. (They were added by an ancestor) )Ú frozensetrr*s rrzChangingFiles.addedVs€ô˜Ÿ™Ó%Ð%r!cóz—dt|«vr|`|jj|«|j |«y)Nr)ÚvarsrrÚaddÚ mark_touched©rÚfilenames rÚ mark_addedzChangingFiles.mark_addedcs1€Ø ”d˜4“jÑ Ø� Ø � ‰ �‰˜Ô!Ø ×ј(Õ#r!có4—|D]}|j|«Œyr#)r4©rÚ filenamesÚfs rÚ update_addedzChangingFiles.update_addedis€ÛˆAØ �O‰O˜AÕ ñr!có,—t|j«S)zËfiles actively merged during a merge Any modified files which had modification on both size that needed merging. In this case a new filenode was created and it has two parents. )r-rr*s rrzChangingFiles.mergedms€ô˜Ÿ™Ó&Ð&r!cóz—dt|«vr|`|jj|«|j |«y)Nr)r/rrr0r1r2s rÚ mark_mergedzChangingFiles.mark_mergedws3€Ø ”t˜D“zÑ !Ø� Ø � ‰ ×јÔ"Ø ×ј(Õ#r!có4—|D]}|j|«Œyr#)r<r6s rÚ update_mergedzChangingFiles.update_merged}s€ÛˆAØ × Ñ ˜QÕ ñr!có,—t|j«S)afiles actively removed by the changeset In case of merge this will only contain the set of files removing "new" content. For any file absent in the current changeset: a) If the file exists in both parents, it is clearly "actively" removed by this changeset. b) If a file exists in only one parent and in none of the common ancestors, then the file was newly added in one of the merged branches and then got "actively" removed. c) If a file exists in only one parent and at least one of the common ancestors using the same filenode, then the file was unchanged on one side and deleted on the other side. The merge "passively" propagated that deletion, but didn't "actively" remove the file. In this case the file is *not* included in the `removed` set. d) If a file exists in only one parent and at least one of the common ancestors using a different filenode, then the file was changed on one side and removed on the other side. The merge process "actively" decided to drop the new change and delete the file. Unlike in the previous case, (c), the file included in the `removed` set. Summary table for merge: case | exists in parents | exists in gca || removed (a) | both | * || yes (b) | one | none || yes (c) | one | same filenode || no (d) | one | new filenode || yes )r-rr*s rrzChangingFiles.removed�s€ôD˜Ÿ™Ó'Ð'r!cóz—dt|«vr|`|jj|«|j |«y)Nr)r/rrr0r1r2s rÚ mark_removedzChangingFiles.mark_removed¥s3€Ø œ˜T› Ñ "Ø� Ø � ‰ ×ј(Ô#Ø ×ј(Õ#r!có4—|D]}|j|«Œyr#)rAr6s rÚupdate_removedzChangingFiles.update_removed«ó€ÛˆAØ × Ñ ˜aÕ ñr!có,—t|j«S)a.files that might have been deleted by a merge, but still exists. During a merge, the manifest merging might select some files for removal, or for a removed/changed conflict. If at commit time the file still exists, its removal was "reverted" and the file is "salvaged" )r-rr*s rrzChangingFiles.salvaged¯s€ô˜Ÿ™Ó(Ð(r!cóz—dt|«vr|`|jj|«|j |«y)Nr)r/rrr0r1r2s rÚ mark_salvagedzChangingFiles.mark_salvaged¹s3€Ø œ˜d›Ñ #Ø� Ø �‰×ј8Ô$Ø ×ј(Õ#r!có4—|D]}|j|«Œyr#)rGr6s rÚupdate_salvagedzChangingFiles.update_salvaged¿s€ÛˆAØ × Ñ ˜qÕ !ñr!có,—t|j«S)z0files either actively modified, added or removed)r-rr*s rrzChangingFiles.touchedÃs€ô˜Ÿ™Ó'Ð'r!cóX—dt|«vr|`|jj|«y)Nr)r/rrr0r2s rr1zChangingFiles.mark_touchedÈs%€Ø œ˜T› Ñ "Ø� Ø � ‰ ×ј(Õ#r!có4—|D]}|j|«Œyr#)r1r6s rÚupdate_touchedzChangingFiles.update_touchedÍrDr!có6—|jj«Sr#)rÚcopyr*s rr$zChangingFiles.copied_from_p1Ñó€à�‰×#Ñ#Ó%Ð%r!có@—dt|«vr|`||j|<y)Nr$)r/r$r©rÚsourceÚdests rÚmark_copied_from_p1z!ChangingFiles.mark_copied_from_p1Õó"€Ø œt D›zÑ )ØÐ#Ø &ˆ�‰˜Òr!cóX—|j«D]\}}|j||«Œyr#)ÚitemsrU©rÚcopiesrTrSs rÚupdate_copies_from_p1z#ChangingFiles.update_copies_from_p1Úó&€Ø"ŸL™LžN‰LˆD�&Ø × $Ñ $ V¨TÕ 2ñ+r!có6—|jj«Sr#)rrOr*s rr%zChangingFiles.copied_from_p2ÞrPr!có@—dt|«vr|`||j|<y)Nr%)r/r%rrRs rÚmark_copied_from_p2z!ChangingFiles.mark_copied_from_p2ârVr!cóX—|j«D]\}}|j||«Œyr#)rXr_rYs rÚupdate_copies_from_p2z#ChangingFiles.update_copies_from_p2çr\r!)NNNNNNN)Ú__name__Ú __module__Ú __qualname__Ú__doc__r r'Úpropertyr+rÚ propertycacherr4r9rr<r>rrArCrrGrIrr1rMr$rUr[r%r_rar r!rr r s:„ñð(ØØØØØØóGò*  ðñ óð ð ×Ññ &óð &ò$ò ð ×Ññ'óð'ò$ò  ð ×Ññ!(óð!(òF$ò !ð ×Ññ)óð)ò$ò "ð ×Ññ(óð(ò$ò !ð ×Ññ&óð&ò'ò 3ð ×Ññ&óð&ò'ó 3r!r có—|j«}|j«}|j«tk(r"|j«tk(r t |«S|j«tk7r#|j«tk(r t ||«S|j«tk(r%|j«tk7rt ||d¬«S|j«|j«k(r t ||«St |||«S)z'compute the files changed by a revisioné)Úparent)Úp1Úp2ÚrevrÚ _process_rootÚ_process_linearÚ_process_merge)Úctxrkrls rÚcompute_all_files_changesrrìsÀ€à �‰‹€BØ �‰‹€BØ ‡v�vƒx”7Ò˜rŸv™v›x¬7Ò2ܘSÓ!Ð!Ø �‰‹”WÒ  §¡£¬WÒ!4ܘr 3Ó'Ð'Ø �‰‹”WÒ  §¡£¬WÒ!4ä˜r 3¨qÔ1Ð1Ø �‰‹�R—V‘V“XÒ ä˜r 3Ó'Ð'ä˜b " cÓ*Ð*r!cój—t«}|j«}|D]}|j|«Œ|S)zEcompute the appropriate changed files for a changeset with no parents)r Úmanifestr4)rqÚmdrtr3s rrnrnþs1€ô ‹€BØ�|‰|‹~€HÛˆØ � ‰ �hÕðà €Ir!có —t«}|j«}|j«}g}|j|«j«D][\}}|dd€|j |«Œ |j |«|dd€|j |«ŒK|j|«Œ]|dk(r |j} n|dk(r |j} n Jd|z«‚|D]&}||j«} | sŒ| \} } | | |«Œ(|S)zJcompute the appropriate changed files for a changeset with a single parentrrrizbad parent value %d) r rtÚdiffrXrAÚappendr4r1rUr_Úrenamed) Ú parent_ctxÚ children_ctxrjruÚparent_manifestÚchildren_manifestÚcopies_candidater3ÚdÚcopiedÚ copy_inforSÚsrcnodes rroros€ä ‹€BØ ×)Ñ)Ó+€OØ$×-Ñ-Ó/ÐàÐà&×+Ñ+Ð,=Ó>×DÑDÖF‰ ˆ�!Ø ˆQ‰4�‰7ˆ?à �O‰O˜HÕ %à × #Ñ # HÔ -Ø�‰t�A‰wˆà— ‘ ˜hÕ'ð—‘ Õ)ðGð�‚{Ø×'Ñ'‰Ø �1ŠØ×'Ñ'‰à4Ð+¨fÑ4Ó4ˆuã$ˆØ  Ñ*×2Ñ2Ó4ˆ Ú Ø'‰OˆF�GÙ �6˜8Õ $ð %ð €Ir!cóô‡—|j«}t«}|j«}|j«}|j«}|j|«}|j|«} |j«jj |j «|j ««} | stg} | D� cgc]#} |j«| j«‘Œ%} } g} |j«D�]O\Š}| j‰d«}|€t|| ‰|«Œ*|dd€+|dd€#|j‰«| j‰«Œ]|dd€|dd€|j‰«Œ|dd�Ä|dd�¼|dd�|dd€8tˆfd„| D««r|j‰«ns|j!‰«na|j#‰|dd¬«}|j%«j'«tk(r|j!‰«n|j)‰«| j‰«�ŒKJd«‚| j«D]\Š}t|| ‰|«Œ| D]xŠ|‰j+«}|sŒ|\}}||vr)||j-«|k(r|j/|‰«ŒK||vsŒP||j-«|k(sŒg|j1|‰«Œz|Scc} w)u·compute the appropriate changed files for a changeset with two parents This is a more advance case. The information we need to record is summarise in the following table: ┌──────────────┬──────────────┬──────────────┬──────────────┬──────────────â”� │ diff ╲ diff │ ø │ (Some, None) │ (None, Some) │ (Some, Some) │ │ p2 ╲ p1 │ │ │ │ │ ├──────────────┼──────────────┼──────────────┼──────────────┼──────────────┤ │ │ │🄱 No Changes │🄳 No Changes │ │ │ ø │🄰 No Changes │ OR │ OR │🄵 No Changes │ │ │ │🄲 Deleted[1] │🄴 Salvaged[2]│ [3] │ ├──────────────┼──────────────┼──────────────┼──────────────┼──────────────┤ │ │🄶 No Changes │ │ │ │ │ (Some, None) │ OR │🄻 Deleted │ ø │ ø │ │ │🄷 Deleted[1] │ │ │ │ ├──────────────┼──────────────┼──────────────┼──────────────┼──────────────┤ │ │🄸 No Changes │ │ │ 🄽 Touched │ │ (None, Some) │ OR │ ø │🄼 Added │OR 🅀 Salvaged │ │ │🄹 Salvaged[2]│ │ (copied?) │ (copied?) │ ├──────────────┼──────────────┼──────────────┼──────────────┼──────────────┤ │ │ │ │ 🄾 Touched │ 🄿 Merged │ │ (Some, Some) │🄺 No Changes │ ø │OR ðŸ…� Salvaged │OR 🅂 Touched │ │ │ [3] │ │ (copied?) │ (copied?) │ └──────────────┴──────────────┴──────────────┴──────────────┴──────────────┘ Special case [1]: The situation is: - parent-A: file exists, - parent-B: no file, - working-copy: no file. Detecting a "deletion" will depend on the presence of actual change on the "parent-A" branch: Subcase 🄱 or 🄶 : if the state of the file in "parent-A" is unchanged compared to the merge ancestors, then parent-A branch left the file untouched while parent-B deleted it. We simply apply the change from "parent-B" branch the file was automatically dropped. The result is: - file is not recorded as touched by the merge. Subcase 🄲 or 🄷 : otherwise, the change from parent-A branch were explicitly dropped and the file was "deleted again". From a user perspective, the message about "locally changed" while "remotely deleted" (or the other way around) was issued and the user chose to deleted the file. The result: - file is recorded as touched by the merge. Special case [2]: The situation is: - parent-A: no file, - parent-B: file, - working-copy: file (same content as parent-B). There are three subcases depending on the ancestors contents: - A) the file is missing in all ancestors, - B) at least one ancestor has the file with filenode ≠ from parent-B, - C) all ancestors use the same filenode as parent-B, Subcase (A) is the simpler, nothing happend on parent-A side while parent-B added it. The result: - the file is not marked as touched by the merge. Subcase (B) is the counter part of "Special case [1]", the file was modified on parent-B side, while parent-A side deleted it. However this time, the conflict was solved by keeping the file (and its modification). We consider the file as "salvaged". The result: - the file is marked as "salvaged" by the merge. Subcase (C) is subtle variation of the case above. In this case, the file in unchanged on the parent-B side and actively removed on the parent-A side. So the merge machinery correctly decide it should be removed. However, the file was explicitly restored to its parent-B content before the merge was commited. The file is be marked as salvaged too. From the merge result perspective, this is similar to Subcase (B), however from the merge resolution perspective they differ since in (C), there was some conflict not obvious solution to the merge (That got reversed) Special case [3]: The situation is: - parent-A: file, - parent-B: file (different filenode as parent-A), - working-copy: file (same filenode as parent-B). This case is in theory much simple, for this to happens, this mean the filenode in parent-A is purely replacing the one in parent-B (either a descendant, or a full new file history, see changeset). So the merge introduce no changes, and the file is not affected by the merge... However, in the wild it is possible to find commit with the above is not True. For example repository have some commit where the *new* node is an ancestor of the node in parent-A, or where parent-A and parent-B are two branches of the same file history, yet not merge-filenode were created (while the "merge" should have led to a "modification"). Detecting such cases (and not recording the file as modified) would be a nice bonus. However do not any of this yet. Nrrc3ó:•K—|]}t|‰«du–—Œy­wr#©Ú_find©Ú.0Úmar3s €rÚ z!_process_merge..Åsøèø€ÐIÁS¸rœ5  XÓ.°dÔ:ÁSùóƒ)ÚfileidÚ unreachable)Úrepor rtrwÚ changelogÚcommonancestorsheadsÚnoderrXÚpopÚ_process_other_unchangedr4rxrAÚanyrGr1Úfilectxrlrmr<ryÚfilenoderUr_)Úp1_ctxÚp2_ctxrqrŽruÚmÚp1mÚp2mÚdiff_p1Údiff_p2ÚcahsÚrÚmasÚcopy_candidatesÚd1Úd2Úfctxr�rSr‚r3s @rrprp-sÊø€ð^ �8‰8‹:€DÜ ‹€Bà � ‰ ‹€AØ �/‰/Ó €CØ �/‰/Ó €CØ�h‰h�q‹k€GØ�h‰h�q‹k€Gà �8‰8‹:× Ñ × 4Ñ 4Ø� ‰ ‹ �v—{‘{“}ó €Dñ ܈yˆÙ-1Ó 2©T¨ˆ3�8‰8‹:�a‰=× !Ñ !Õ #¨T€CÐ 2à€Oð Ÿ ™ Ÿ‰ ˆ�"à �[‰[˜ 4Ó (ˆà ˆ:ä $ R¨¨h¸Õ ;ð�!‰u�Q‰xРB q¡E¨!¡HÐ$4à— ‘ ˜hÔ'Ø×&Ñ& xÕ0Ø�A‘�q‘Ð! b¨¡e¨A¡hÐ&6à—‘ Õ)Ø�A‘�q‘Ð%¨"¨Q©%°©(Ð*>Ø�a‘5˜‘8Ð# r¨!¡u¨Q¡xÐ'7ÜÓIÁSÓIÔIà×(Ñ(¨Õ2🙨Õ1àŸ<™<¨¸¸A¹¸q¹˜<ÓB�DØ—w‘w“y—}‘}“¬'Ò1🙨Õ1🙠xÔ0Ø×&Ñ& xÖ0ð,˜mÓ+�uðM(ðT Ÿ ™ ž‰ ˆ�"Ü   S¨(°BÕ7ð(ó$ˆØ˜‘M×)Ñ)Ó+ˆ Ú Ø'‰OˆF�GؘѠF¨6¡N×$;Ñ$;Ó$=ÀÒ$HØ×&Ñ& v¨xÕ8ؘ6Ò! f¨V¡n×&=Ñ&=Ó&?À7Ó&JØ×&Ñ& v¨xÕ8ð$ð €Iùò} 3sÃ(K5có4—||vry|j|«dS)z%return the associate filenode or NoneNr©Úfind)rtr3s rr†r†ës!€à�xÑØØ �=‰=˜Ó " 1Ñ %Ð%r!có쇇—|ddŠ|dd}‰�*|€(tˆˆfd„|D««r|j‰«yy‰€)|�'tˆfd„|D««r|j‰«yy‰�|�yJd«‚)Nrrc3ó>•K—|]}t|‰«‰k( –—Œy­wr#r…)rˆr‰r3Ú source_nodes €€rrŠz+_process_other_unchanged..÷s!øèø€ÐDÁ¸"”5˜˜XÓ&¨+Ñ5Ô5Áùsƒc3ó:•K—|]}t|‰«du–—Œy­wr#r…r‡s €rrŠz+_process_other_unchanged..üsøèø€Ð=¹°2Œu�R˜Ó"¨$Ô.¹ùr‹r�)r”rArG)rur r3rwÚ target_noderªs ` @rr“r“òs”ù€Ø�q‘'˜!‘*€KØ�q‘'˜!‘*€KàР;Ð#6Ü ÔDÁÓDÔ Dà �O‰O˜HÕ %ð Eð Ð  Ð!8Ü Ó=¹Ó=Ô =à × Ñ ˜XÕ &ð >ð Ð  [Ð%<ð ð $�mÓ#ˆur!có,‡—tˆfd„|D««S)Nc3ó:•K—|]}t|‰«du–—Œy­wr#r…r‡s €rrŠz._missing_from_all_ancestors..søèø€Ð9±S¨rŒu�R˜Ó" dÔ*±Sùr‹©Úall)r r3s `rÚ_missing_from_all_ancestorsr± sø€Ü Ó9±SÓ9Ó 9Ð9r!c󞇗g}|j«D]6Štˆfd„|j«D««rŒ&|j‰«Œ8|S)z-return the list of files added in a changesetc3ó&•K—|]}‰|v–—Œ y­wr#r )rˆÚpr8s €rrŠz-computechangesetfilesadded..søèø€Ð1¡=˜a�1˜”6¡=ùsƒ)Úfilesr”Úparentsrx)rqrr8s @rÚcomputechangesetfilesaddedr·s>ø€à €EØ �Y‰YŽ[ˆÜÓ1 3§;¡;¤=Ó1Õ1Ø �L‰L˜�Oðð €Lr!có臇‡‡‡‡—|�|\ŠŠŠŠn@‰j«Š‰j«Š‰j«Š‰j«Štjˆˆˆfd„«Šˆˆˆfd„}|S)a<return a function to detect files "wrongly" detected as `removed` When a file is removed relative to p1 in a merge, this function determines whether the absence is due to a deletion from a parent, or whether the merge commit itself deletes the file. We decide this by doing a simplified three way merge of the manifest entry for the file. There are two ways we decide the merge itself didn't delete a file: - neither parent (nor the merge) contain the file - exactly one parent contains the file, and that parent has the same filelog entry as the merge ancestor (or all of them if there two). In other words, that parent left the file unchanged while the other one deleted it. One way to think about this is that deleting a file is similar to emptying it, so the list of changed files should be similar either way. The computation described above is not done directly in _filecommit when creating the list of changed files, however it does something very similar by comparing filelog nodes. có•—‰j«}‰j«}‰j«jj||«}|stg}|D�cgc]#}‰j«|j «‘Œ%c}Scc}wr#)r‘rŽr�r�rrt)Úp1nÚp2nržrŸrqrkrls €€€rr zget_removal_filter..mas;slø€à�g‰g‹iˆØ�g‰g‹iˆØ�x‰x‹z×#Ñ#×8Ñ8¸¸cÓBˆÙÜ�9ˆDÙ26Ó7±$¨Q�—‘“ ˜1‘ ×&Ñ&Õ(°$Ñ7Ð7ùÒ7sÁ(Bc󌕇—‰‰vr ‰‰vxrtˆˆfd„‰«D««S‰‰vrtˆˆfd„‰«D««Sy)Nc3óp•K—|]-}‰|vxr#|j‰«‰j‰«k(–—Œ/y­wr#r¦)rˆr‰r8Úm1s €€rrŠzAget_removal_filter..deletionfromparent..Fs6øèø€ð'Ù?D¸��R�Ò4˜BŸG™G A›J¨"¯'©'°!«*Ñ4Ó4¹uùóƒ36c3óp•K—|]-}‰|vxr#|j‰«‰j‰«k(–—Œ/y­wr#r¦)rˆr‰r8Úm2s €€rrŠzAget_removal_filter..deletionfromparent..Js3øèø€ÐLÁeÀ�q˜B�wÒ; 2§7¡7¨1£:°·±¸³Ñ#;Ó;Áeùr¿Tr¯)r8r¾rÁr s`€€€rÚdeletionfromparentz.get_removal_filter..deletionfromparentDsPù€Ø �‰7ؘB�;ò¤3ô'Ù?B¼uó'ó$ð ð�"‰WÜÔLÁcÄeÓLÓLÐ Làr!)rkrlrtrÚ cachefunc)rqÚxrÂr¾rÁr rkrls` @@@@@rÚget_removal_filterrÅsfý€ð2 €}؉ˆˆB�‘Bà �V‰V‹XˆØ �V‰V‹XˆØ �[‰[‹]ˆØ �[‰[‹]ˆä ‡^�^õ8óð8öð Ðr!có´—g}|j«D]}||vsŒ|j|«Œ|r#t|«}|D�cgc] }||«rŒ |‘Œ}}|Scc}w)z/return the list of files removed in a changeset)rµrxrÅ)rqrr8ÚrfrŸs rÚcomputechangesetfilesremovedrÈQs]€à€GØ �Y‰YŽ[ˆØ �CŠ<Ø �N‰N˜1Õ ðñÜ  Ó $ˆÙ%Ó3™g˜©R°­U’1˜gˆÐ3Ø €Nùò4s ¿ AÁ Acó2—g}t|j««dkr|S|j«D]c}||vsŒ||}|jj|j«}|d|j «j k7sŒS|j|«Œe|S)z.return the list of files merged in a changesetrir)Úlenr¶rµÚ_filelogÚ _filenoderŽÚnullidrx)rqrr8r¤r¶s rÚcomputechangesetfilesmergedrÎ]s‚€à €FÜ ˆ3�;‰;‹=Ó˜AÒØˆ Ø �Y‰YŽ[ˆØ �Š8Ø�q‘6ˆDØ—m‘m×+Ñ+¨D¯N©NÓ;ˆGØ�q‰z˜SŸX™X›Z×.Ñ.Ó.Ø— ‘ ˜aÕ ð ð €Mr!có‚—i}i}|j«}|j«}|jj«}|j «D]k}||«r||vrŒ||j «}|sŒ&|\}} ||vr||j «| k(r|||<ŒK||vsŒP||j «| k(sŒg|||<Œm||fS)z¸return the copies data for a changeset The copies data are returned as a pair of dictionnary (p1copies, p2copies). Each dictionnary are in the form: `{newname: oldname}` )rkrlÚ_repoÚ narrowmatchrµryr–) rqÚp1copiesÚp2copiesrkrlrÑÚdstr€Úsrcr‚s rÚcomputechangesetcopiesrÖksÍ€ð€HØ€HØ �‰‹€BØ �‰‹€BØ—)‘)×'Ñ'Ó)€KØ�y‰yŽ{ˆÙ˜3Ô 3¨c¡>Ø Ø�S‘×!Ñ!Ó#ˆÙØ Ø‰ ˆˆWØ �"‰9˜˜C™×)Ñ)Ó+¨wÒ6؈H�SŠMØ �BŠY˜2˜c™7×+Ñ+Ó-°Ó8؈H�SŠMðð �XÐ Ðr!cóâ—g}t|«D]#\}}||vsŒ |jd|||fz«Œ%t|«t|«k7rtjd«‚dj |«S)Ns%d%ss(some copy targets missing from file listó )Ú enumeraterxrÊrÚProgrammingErrorÚjoin)rµrZrXÚirÔs rÚ encodecopiesrÝ…st€Ø €EܘEÖ"‰ˆˆ3Ø �&Š=Ø �L‰L˜ a¨°©Ð%5Ñ5Õ 6ð#ô ˆ5ƒz”S˜“[Ò Ü×$Ñ$Ø 7ó ð ð �:‰:�eÓ Ðr!có¼— i}|s|S|jd«D]+}|jd«\}}t|«}||}|||<Œ-|S#ttf$rYywxYw)NrØó)ÚsplitÚintÚ ValueErrorÚ IndexError)rµÚdatarZÚlÚstrindexrÕrÜrÔs rÚ decodecopiesrç‘ss€ð ØˆÙØˆMØ—‘˜EÖ"ˆAØŸG™G E›N‰MˆH�cÜ�H“ ˆAؘ‘(ˆC؈F�3ŠKð #ð ˆ øÜ œ Ð #òñðús‚A ˆAA Á AÁAcó–—t|«}g}t|«D]\}}||vsŒ |jd|z«Œ dj|«S)Ns%drØ)r rÙrxrÛ)rµÚsubsetÚindicesrÜr8s rÚencodefileindicesrë¢sK€Ü �‹[€FØ€Gܘ%Ö ‰ˆˆ1Ø �Š;Ø �N‰N˜5 1™9Õ %ð!ð �:‰:�gÓ Ðr!cóÒ— g}|s|S|jd«D]6}t|«}|dks|t|«k\ry|j||«Œ8|S#tt f$rYywxYw)NrØr)ràrárÊrxrârã)rµrärérærÜs rÚdecodefileindicesrí«st€ð ØˆÙØˆMØŸ ™  5Ö)ˆHÜ�H“ ˆAØ�1Šu˜œS ›ZšÙØ �M‰M˜% ™(Õ #ð *ð ˆ øÜ œ Ð #òñðús‚Aˆ3A¼AÁA&Á%A&Ú11100riÚ00100Ú01000Ú01100Ú10000Ú10100Ú11Ú10z>Lz>bLLcó&—t|j«}|j|jj ««|j|j j ««t |«}t|«D��cic]\}}||“Œ }}}d|d<tjt|««g}d}|D�]}t|«}||z }d}||jvr |tz}n_||jvr |tz}nG||jvr |t z}n/||j"vr |t$z}n||jvr |t&z}d} ||jvr%|t(z}|jj+|«} n2||j vr$|j j+|«} |t,z}|| } |j/t0j||| ««�Œ!|j3|«t4j6dj9|«iScc}}w)Nrr!)r rrr$Úvaluesr%ÚsortedrÙÚ INDEX_HEADERÚpackrÊrÚ ADDED_FLAGrÚ MERGED_FLAGrÚ REMOVED_FLAGrÚ SALVAGED_FLAGÚ TOUCHED_FLAGÚCOPIED_FROM_P1_FLAGÚgetÚCOPIED_FROM_P2_FLAGrxÚ INDEX_ENTRYÚextendÚ sidedatamodÚSD_FILESrÛ) rµÚ all_filesrÜr8Úfile_idxÚchunksÚfilename_lengthÚ filename_sizeÚflagrOÚcopy_idxs rÚencode_files_sidedatarÏsà€Ü�E—M‘MÓ"€IØ ×Ñ�U×)Ñ)×0Ñ0Ó2Ô3Ø ×Ñ�U×)Ñ)×0Ñ0Ó2Ô3Ü�yÓ!€IÜ#,¨YÔ#7Ô8Ñ#7™˜!˜Q��1‘Ð#7€HÑ8Ø€HˆT�Nä×Ѥ I£Ó/Ð 0€Fà€OÜ ˆÜ˜A›ˆ ؘ=Ñ(ˆØˆØ �— ‘ Ñ Ø ”JÑ ‰DØ �%—,‘,Ñ Ø ”KÑ ‰DØ �%—-‘-Ñ Ø ”LÑ ‰DØ �%—.‘.Ñ Ø ”MÑ !‰DØ �%—-‘-Ñ Ø ”LÑ ˆDàˆØ �×$Ñ$Ñ $Ø Ô'Ñ 'ˆDØ×'Ñ'×+Ñ+¨AÓ.‰DØ �%×&Ñ&Ñ &Ø×'Ñ'×+Ñ+¨AÓ.ˆDØ Ô'Ñ 'ˆDؘD‘>ˆØ� ‰ ”k×&Ñ& t¨_¸hÓGÖHð/ð0 ‡M�M�)ÔÜ × Ñ  #§(¡(¨6Ó"2Ð 3Ð3ùó?9s H cóN—t«}|jtj«}|€|Sg}g}t |«t j k\sJ‚t j|d«d}t j }|tj |zz}|}t |«|k\sJ‚t|«D�]^} tj||«\} } } | |z } ||| } | |z }t | «|k(sJ‚|tj z }| }|j| «| tztk(r|j| «n‡| tztk(r|j| «ne| tzt k(r|j#| «nC| tzt$k(r|j'| «n!| tzt(k(r|j+| «d}| t,zt.k(r |j0}n| t,zt2k(r |j4}|€�ŒK|j|| | f«�Œa|D]\}} } ||| | «Œ|S©Nr)r rrrrÊrùÚsizeÚ unpack_fromrÚrangerxÚ ACTION_MASKrûr4rür<rýrArþrGrÿr1Ú COPIED_MASKrrUrr_)rruÚrawrZrÚ total_filesÚoffsetÚfile_offset_baseÚfile_offset_lastÚidxr Úfile_endr r3Úfilesizer€s rÚdecode_files_sidedatarös€Ü ‹€BØ �,‰,”{×+Ñ+Ó ,€Cà €{؈ à €FØ€Iä ˆs‹8”|×(Ñ(Ò (Ð(Ð (Ü×*Ñ*¨3°Ó2°1Ñ5€Kä × Ñ €Fؤ×!1Ñ!1°KÑ!?Ñ@ÐØ'Ðä ˆs‹8Ð'Ò 'Ð'Ð 'ä�[×!ˆÜ#.×#:Ñ#:¸3ÀÓ#GÑ ˆˆh˜ØÐ$Ñ$ˆØÐ'¨Ð1ˆØÐ.Ñ.ˆÜ�8‹} Ò(Ð(Ð(Ø”+×"Ñ"Ñ"ˆØ#ÐØ×јÔ"Ø ”+Ñ ¤Ò +Ø �M‰M˜(Õ #Ø ”KÑ ¤;Ò .Ø �N‰N˜8Õ $Ø ”KÑ ¤<Ò /Ø �O‰O˜HÕ %Ø ”KÑ ¤=Ò 0Ø × Ñ ˜XÕ &Ø ”KÑ ¤<Ò /Ø �O‰O˜HÔ %àˆØ ”+Ñ Ô!4Ò 4Ø×+Ñ+‰FØ ”KÑ Ô#6Ò 6Ø×+Ñ+ˆFà Ò Ø �M‰M˜6 8¨XÐ6Ö 7ð7"ó:'-Ñ"ˆ�˜(Ùˆy˜Ñ" HÕ-ð'-ð €Ir!cóP—||}t|«}t|«|jfSr#)rrrr+)Úsrcrepormrqrµs rÚ _getsidedatar!,s+€Ø �#‰,€CÜ % cÓ *€EÜ  Ó '¨×)>Ñ)>Ð >Ð>r!cóT—t||«\}}|rtjnd}||dffSr)r!Ú sidedataflagÚREVIDX_HASCOPIESINFO)rŽÚrevlogrmÚexisting_sidedatarr+Ú flags_to_adds rÚcopies_sidedata_computerr(2s2€Ü ,¨T°3Ó 7Ñ€HˆoÙ8G”<×4Ò4ÈQ€LØ �l AÐ&Ð &Ð&r!cóì—|j«|j«}|�Bt||«}|j||f«|j«|j«}|�ŒB|j «y)aºThe function used by worker precomputing sidedata It read an input queue containing revision numbers It write in an output queue containing (rev, ) The `None` input value is used as a stop signal. The `tokens` semaphore is user to avoid having too many unprocessed entries. The workers needs to acquire one token before fetching a task. They will be released by the consumer of the produced data. N)Úacquirerr!ÚputÚrelease)r Ú revs_queueÚsidedata_queueÚtokensrmräs rÚ_sidedata_workerr08sf€ð ‡N�NÔØ �.‰.Ó €CØ ˆ/ܘG SÓ)ˆØ×јC ˜;Ô'Ø�‰ÔØ�n‰nÓˆð ‰/ð  ‡N�NÕr!é2cóN‡ ‡ ‡ —ddlm}|j|j«}t j |t z«Š t j«}t j«Š |j�J‚|jj«D]}|j|«Œt|«D]}|jd«Œg}t|«D]D}||‰ ‰ f}t jt|¬«} |j| «| j!«ŒFiŠ ˆ ˆ ˆ fd„} | S)zœThe parallel version of the sidedata computation This code spawn a pool of worker that precompute a buffer of sidedata before we actually need themr)ÚworkerN)ÚtargetÚargscóö•—‰ j|d«}|€6‰ j«\}}||k7r|‰ |<‰ j«\}}||k7rŒ‰ j«|\}}d}|rtj}||dffSr)r’rr,r#r$) rŽr%rmÚ old_sidedatarärŸrr+Únew_flagÚ sidedataqÚstagingr/s €€€rÚsidedata_companionz6_get_worker_sidedata_adder..sidedata_companionzs‰ø€à�{‰{˜3 Ó%ˆØ ˆ<ð —m‘m“o‰GˆAˆtØ�s’(Ø!�˜‘ Ø#Ÿ-™-›/‘��4ð�s“(ð �‰ÔØ$(Ñ!ˆ�/؈٠Ü#×8Ñ8ˆHؘ( A˜Ð&Ð&r!)Úr3Ú _numworkersÚuiÚmultiprocessingÚBoundedSemaphoreÚBUFF_PER_WORKERÚQueueÚ filternamer�Úrevsr+rÚProcessr0rxÚstart)r Údestrepor3Ú nbworkersÚrevsqrŸrÜÚ allworkersr5Úwr;r9r:r/s @@@rÚ_get_worker_sidedata_adderrLRsú€õ à×"Ñ" 7§:¡:Ó.€Iä × -Ñ -¨i¼/Ñ.IÓ J€FÜ × !Ñ !Ó #€EÜ×%Ñ%Ó'€Ià × Ñ Ð %Ð%Ð %ð× Ñ × #Ñ #Ö %ˆØ � ‰ �!� ð&ô�9Ö ˆØ � ‰ �$�ðð€JÜ �9Ö ˆØ˜  ¨6Ð2ˆÜ × #Ñ #Ô+;À$Ô GˆØ×ј!ÔØ �‰� ð ð€Gö'ð" Ðr!)rr#)1r?Ústructr‘rr<rrÚ revlogutilsrr#rrr rrrnrorpr†r“r±r·rÅrÈrÎrÖrÝrçrërírárrûrürýrþrÿrrrÚStructrùrrrr!r(r0rArLr r!rÚrPs1ðóÛ å÷÷ ÷ P3ñP3òf+ò$ó"òJ{ò|&ò$ò6:òó4òn ò òò4 òò"òñ&�*˜aÓ € á �˜QÓ € Ù�*˜aÓ € Ù�:˜qÓ!€ Ù�J Ó"€ Ù�:˜qÓ!€ á�$˜‹l€ Ù˜$ “lÐÙ˜$ “lÐðˆv�}‰}˜TÓ"€ ؈f�m‰m˜FÓ#€ ò$4òN3òl?ò 'ò ð.€ó9r!