{"state":{"revisions":[{"id":"12627","callsign":"HG","title":"worker: adapt _blockingreader to work around a python3.8.[0-1] bug (issue6444)","author":"mharbison72","summary":"Python 3.8.0 is the latest I can load on Ubuntu 18.04, and I regularly hit the\nTypeError because this function is missing. While it can be avoided by\ndisabling worker usage via config option, that's a bit obscure.\n\nI'm limiting the function definition to the narrow range of affected pythons\nbecause there were other bugs in this area that were worked around, that I don't\nfully understand. See the bug report for discussions on why the narrow range,\nand related commits working around other bugs.","testPlan":"","lineCount":"17","dependsOn":[],"reviewers":["mjacob","Alphare"],"ccs":["martinvonz","Alphare","mjacob","mercurial-patches"],"actions":[{"type":"comment","comment":">>! In D12627#193350, @Alphare wrote:\n>\n> @mharbison72 you should have no trouble at all since you're already using Hetpapod for the CI. Please read the contributor guide here: https:\/\/www.mercurial-scm.org\/wiki\/Heptapod\n> \n> I hope I'm clear, it's very late and my brain is half-working. :)\n\nDone. I couldn't remember where I saw these instructions, and I created it before you responded here, but I think I did it right. I don't see a \"Ready\" button now, but I do see one \"Mark as Draft\", so I assume it's already in that state.\n\nIs there any way to link that wiki page from the top of the page that creates the merge request, for easier discoverability by new users?\n","author":"mharbison72","id":"193381","dateCreated":"1652973440","dateModified":"1652973440"},{"type":"comment","comment":"> I *think* you're supposed to open a \"merge request\" on https:\/\/foss.heptapod.net\/mercurial\/mercurial-devel these days. Right, @Alphare?\n\nRight! \n\n> I didn't think we made the switch yet, but I'm fine doing that as a pilot. (I ended up amending a commit comment typo since the last push, so it will need to run CI again.)\n\nI have actually already merged a couple of MRs using Heptapod.\n\n> The reason I suggested it was that I queued the patch and tried to push it to hg-committed, but that failed and told me to create a merge request instead. So I suppose it's actually you who should create that merge request since it's your patch. I'm not sure I understood it correctly, though.\n\nYup. Phabricator is deprecated and slated for read-only state on\/around June 1st. The deprecation means that any new patches should be sent to Heptapod unless absolutely infeasible (because something is terribly broken), and old patches will be reviewed here, then put in a topic by yours truly for a CI pass and merged accordingly. Any diff that still needs review\/turn-around by June 1st will need to be resent through Heptapod.\n\n@mharbison72 you should have no trouble at all since you're already using Hetpapod for the CI. Please read the contributor guide here: https:\/\/www.mercurial-scm.org\/wiki\/Heptapod\n \nI hope I'm clear, it's very late and my brain is half-working. :)","author":"Alphare","id":"193350","dateCreated":"1652915774","dateModified":"1652915774"},{"type":"reject","author":"Alphare","id":"193349","dateCreated":"1652915774","dateModified":"1652915774"},{"type":"comment","comment":">>! In D12627#193347, @mharbison72 wrote:\n>>>! In D12627#193334, @martinvonz wrote:\n>> I *think* you're supposed to open a \"merge request\" on https:\/\/foss.heptapod.net\/mercurial\/mercurial-devel these days. Right, @Alphare?\n> \n> I didn't think we made the switch yet, but I'm fine doing that as a pilot. (I ended up amending a commit comment typo since the last push, so it will need to run CI again.)\n\nThe reason I suggested it was that I queued the patch and tried to push it to hg-committed, but that failed and told me to create a merge request instead. So I suppose it's actually you who should create that merge request since it's your patch. I'm not sure I understood it correctly, though.","author":"martinvonz","id":"193348","dateCreated":"1652904100","dateModified":"1652904100"},{"type":"comment","comment":">>! In D12627#193334, @martinvonz wrote:\n> I *think* you're supposed to open a \"merge request\" on https:\/\/foss.heptapod.net\/mercurial\/mercurial-devel these days. Right, @Alphare?\n\nI didn't think we made the switch yet, but I'm fine doing that as a pilot. (I ended up amending a commit comment typo since the last push, so it will need to run CI again.)","author":"mharbison72","id":"193347","dateCreated":"1652903973","dateModified":"1652903973"},{"type":"update","diffId":"33407","author":"mharbison72","id":"193336","dateCreated":"1652891789","dateModified":"1652891789"},{"type":"comment","comment":"I *think* you're supposed to open a \"merge request\" on https:\/\/foss.heptapod.net\/mercurial\/mercurial-devel these days. Right, @Alphare?","author":"martinvonz","id":"193335","dateCreated":"1652887926","dateModified":"1652887926"},{"type":"inline","comment":"This could change the size of `b`, which shouldn\u2019t be done.\n\nIf pickle calls `readinto()` (e.g. on my machine, this happens when the pickled data contains a bytestring >= 2**16 bytes long), it passes a memoryview which doesn\u2019t allow changing its size. Because the size of `b` is the size of the pickled object and `readall()` returns all bytes in the stream, containing the bytes for the pickled object + at least one trailing byte, this line would always raise a \u201cValueError: memoryview assignment: lvalue and rvalue have different structures\u201d exception.\n\nWhat I suggest instead is to mostly copy-paste the implementation of `read()` and modify it such that it reads into the provided buffer instead of creating one.","replyTo":null,"isNewFile":"1","line":"86","lineLength":"0","path":"mercurial\/worker.py","diffId":"33406","author":"mjacob","id":"193332","dateCreated":"1652844706","dateModified":"1652844706"},{"type":"reject","author":"mjacob","id":"193331","dateCreated":"1652844706","dateModified":"1652844706"},{"type":"comment","comment":"This is meant for stable.\n\nThe conflict resolution when merging this into default is a simple de-indent.","author":"mharbison72","id":"193329","dateCreated":"1652816069","dateModified":"1652816069"},{"type":"update","diffId":"33406","author":"mharbison72","id":"193324","dateCreated":"1652815997","dateModified":"1652815997"}],"dateCreated":"1652815997","dateModified":"1652973440","status":"Needs Revision"},{"id":"12619","callsign":"HG","title":"auto-upgrade: skip the operation if the repository cannot be locked","author":"marmoute","summary":"This seems like a fine default behavior for now. If some users wants something\nmore aggressive we can make the behavior configurable in the future.","testPlan":"","lineCount":"50","dependsOn":["12618"],"reviewers":[],"ccs":["Kwan","mercurial-patches"],"actions":[{"type":"comment","comment":":white_check_mark: refresh by Heptapod after a successful CI run (:octopus: :green_heart:)","author":"baymax","id":"193380","dateCreated":"1652956604","dateModified":"1652956604"},{"type":"update","diffId":"33417","author":"baymax","id":"193379","dateCreated":"1652956604","dateModified":"1652956604"},{"type":"inline","comment":"s\/attemps\/attempt\/g\n\n","replyTo":null,"isNewFile":"1","line":"961","lineLength":"0","path":"mercurial\/helptext\/config.txt","diffId":"33371","author":"Kwan","id":"193248","dateCreated":"1652277192","dateModified":"1652277192"},{"type":"update","diffId":"33371","author":"marmoute","id":"193119","dateCreated":"1651826271","dateModified":"1651826271"}],"dateCreated":"1651826271","dateModified":"1652956604","status":"Needs Review"},{"id":"12618","callsign":"HG","title":"auto-upgrade: add a test case where the repository is already locked","author":"marmoute","summary":"This show the current behavior when the repository to auto-upgrade is already\nlocked.\n\nThe current behavior is to abort, which is probably not great. Now that we have\na proper test, we can think about the behavior we wants in a later tests.","testPlan":"","lineCount":"15","dependsOn":["12617"],"reviewers":[],"ccs":["mercurial-patches"],"actions":[{"type":"comment","comment":":white_check_mark: refresh by Heptapod after a successful CI run (:octopus: :green_heart:)","author":"baymax","id":"193378","dateCreated":"1652956603","dateModified":"1652956603"},{"type":"update","diffId":"33416","author":"baymax","id":"193376","dateCreated":"1652956603","dateModified":"1652956603"},{"type":"update","diffId":"33370","author":"marmoute","id":"193111","dateCreated":"1651826265","dateModified":"1651826265"}],"dateCreated":"1651826265","dateModified":"1652956603","status":"Needs Review"},{"id":"12617","callsign":"HG","title":"wait-on-file: properly wait on any files and symlink","author":"marmoute","summary":"This make the utility more useful, for example to wait on a lock file.\nWe also add an explicit -L check since the lock are \"weird\" symlink.","testPlan":"","lineCount":"2","dependsOn":["12616"],"reviewers":[],"ccs":["mercurial-patches"],"actions":[{"type":"comment","comment":":white_check_mark: refresh by Heptapod after a successful CI run (:octopus: :green_heart:)","author":"baymax","id":"193375","dateCreated":"1652956602","dateModified":"1652956602"},{"type":"update","diffId":"33415","author":"baymax","id":"193372","dateCreated":"1652956602","dateModified":"1652956602"},{"type":"update","diffId":"33369","author":"marmoute","id":"193103","dateCreated":"1651826260","dateModified":"1651826260"}],"dateCreated":"1651826260","dateModified":"1652956602","status":"Needs Review"},{"id":"12616","callsign":"HG","title":"debuglock: make the command more useful in non-interactive mode","author":"marmoute","summary":"The existing prompt mode simply release the lock immediately in non-interactive\nmode. That is quite useless in the test so now the non-interactive mode simply\nwait for a signal.","testPlan":"","lineCount":"14","dependsOn":["12615"],"reviewers":[],"ccs":["mercurial-patches"],"actions":[{"type":"comment","comment":":white_check_mark: refresh by Heptapod after a successful CI run (:octopus: :green_heart:)","author":"baymax","id":"193371","dateCreated":"1652956601","dateModified":"1652956601"},{"type":"update","diffId":"33414","author":"baymax","id":"193369","dateCreated":"1652956601","dateModified":"1652956601"},{"type":"update","diffId":"33368","author":"marmoute","id":"193095","dateCreated":"1651826255","dateModified":"1651826255"}],"dateCreated":"1651826255","dateModified":"1652956601","status":"Needs Review"},{"id":"12615","callsign":"HG","title":"auto-upgrade: add a test case with no permission to lock the repository","author":"marmoute","summary":"This show the current behavior when the repository is unlockable.\n\nThe current behavior is to abort, which is probably not great. Now that we have\na proper test, we can think about the behavior we want in a later changeset.","testPlan":"","lineCount":"15","dependsOn":["12614"],"reviewers":[],"ccs":["mercurial-patches"],"actions":[{"type":"comment","comment":":white_check_mark: refresh by Heptapod after a successful CI run (:octopus: :green_heart:)","author":"baymax","id":"193368","dateCreated":"1652956600","dateModified":"1652956600"},{"type":"update","diffId":"33413","author":"baymax","id":"193366","dateCreated":"1652956600","dateModified":"1652956600"},{"type":"update","diffId":"33367","author":"marmoute","id":"193087","dateCreated":"1651826249","dateModified":"1651826249"}],"dateCreated":"1651826249","dateModified":"1652956600","status":"Needs Review"},{"id":"12614","callsign":"HG","title":"auto-upgrade: introduce a way to auto-upgrade to\/from dirstate-v2","author":"marmoute","summary":"This is similar to what we introduced for `share-safe`, but apply to the\ntracked-hint feature.","testPlan":"","lineCount":"155","dependsOn":["12613"],"reviewers":[],"ccs":["mercurial-patches"],"actions":[{"type":"comment","comment":":white_check_mark: refresh by Heptapod after a successful CI run (:octopus: :green_heart:)","author":"baymax","id":"193365","dateCreated":"1652956599","dateModified":"1652956599"},{"type":"update","diffId":"33412","author":"baymax","id":"193363","dateCreated":"1652956599","dateModified":"1652956599"},{"type":"update","diffId":"33366","author":"marmoute","id":"193079","dateCreated":"1651826244","dateModified":"1651826244"}],"dateCreated":"1651826244","dateModified":"1652956599","status":"Needs Review"},{"id":"12613","callsign":"HG","title":"auto-upgrade: introduce a way to auto-upgrade to\/from tracked-hint","author":"marmoute","summary":"This is similar to what we introduced for `share-safe`, but apply to the\ntracked-hint feature.","testPlan":"","lineCount":"176","dependsOn":["12612"],"reviewers":["Alphare"],"ccs":["Alphare","mercurial-patches"],"actions":[{"type":"comment","comment":":white_check_mark: refresh by Heptapod after a successful CI run (:octopus: :green_heart:)","author":"baymax","id":"193362","dateCreated":"1652956597","dateModified":"1652956597"},{"type":"update","diffId":"33411","author":"baymax","id":"193360","dateCreated":"1652956597","dateModified":"1652956597"},{"type":"inline","comment":"automatique","replyTo":null,"isNewFile":"1","line":"607","lineLength":"0","path":"tests\/test-share-safe.t","diffId":"33365","author":"Alphare","id":"193308","dateCreated":"1652803505","dateModified":"1652803505"},{"type":"accept","author":"Alphare","id":"193307","dateCreated":"1652803505","dateModified":"1652803505"},{"type":"update","diffId":"33365","author":"marmoute","id":"193071","dateCreated":"1651826238","dateModified":"1651826238"}],"dateCreated":"1651826238","dateModified":"1652956597","status":"Accepted"},{"id":"12612","callsign":"HG","title":"upgrade: split some logic from UpgradeOperation","author":"marmoute","summary":"The logic for automatic-upgrade and the upgrade-repo should be able to use the\nsame code. However that code often need an UpgradeOperation object to function.\nSo we start spliting the Operation into a minimal component that we will be\nable to reuse outside of the \"classic\" upgrade path.\n\nWe will put the base-class to use in the next changeset.","testPlan":"","lineCount":"27","dependsOn":["12611"],"reviewers":["Alphare"],"ccs":["mercurial-patches"],"actions":[{"type":"comment","comment":":white_check_mark: refresh by Heptapod after a successful CI run (:octopus: :green_heart:)","author":"baymax","id":"193359","dateCreated":"1652956596","dateModified":"1652956596"},{"type":"update","diffId":"33410","author":"baymax","id":"193357","dateCreated":"1652956596","dateModified":"1652956596"},{"type":"accept","author":"Alphare","id":"193304","dateCreated":"1652803154","dateModified":"1652803154"},{"type":"update","diffId":"33364","author":"marmoute","id":"193063","dateCreated":"1651826233","dateModified":"1651826233"}],"dateCreated":"1651826233","dateModified":"1652956596","status":"Accepted"},{"id":"12611","callsign":"HG","title":"auto-upgrade: introduce a way to auto-upgrade to\/from share-safe","author":"marmoute","summary":"This is the first \"automatic-upgrade\" capability. In the following commits,\nsimilar features are coming for other \"fast to upgrade\" formats.\n\nThis is different from the `safe-mismatch.source-not-safe` and\n`safe-mismatch.source-safe` configuration that deal with mismatch between a\nshare and its share-source. Here we are dealing with mismatch between a\nrepository configuration and its actual format.\n\nWe will need further work for cases were the repository cannot be locked. A\nbasic protection is in place to avoid a infinite loop for now, but it will get\nproper attention in a later changeset.","testPlan":"","lineCount":"193","dependsOn":["12610"],"reviewers":["Alphare"],"ccs":["Alphare","mercurial-patches"],"actions":[{"type":"comment","comment":":white_check_mark: refresh by Heptapod after a successful CI run (:octopus: :green_heart:)","author":"baymax","id":"193356","dateCreated":"1652956595","dateModified":"1652956595"},{"type":"update","diffId":"33409","author":"baymax","id":"193354","dateCreated":"1652956595","dateModified":"1652956595"},{"type":"comment","comment":"Will amend typos on-the-fly","author":"Alphare","id":"193302","dateCreated":"1652802819","dateModified":"1652802819"},{"type":"accept","author":"Alphare","id":"193301","dateCreated":"1652802819","dateModified":"1652802819"},{"type":"update","diffId":"33363","author":"marmoute","id":"193055","dateCreated":"1651826229","dateModified":"1651826229"}],"dateCreated":"1651826229","dateModified":"1652956595","status":"Accepted"},{"id":"12610","callsign":"HG","title":"rust: make requirements public","author":"marmoute","summary":"These can be used by any client crates (including `rhg`), no need to make them\nprivate to the crate.","testPlan":"","lineCount":"28","dependsOn":[],"reviewers":["Alphare"],"ccs":["mercurial-patches"],"actions":[{"type":"accept","author":"Alphare","id":"193298","dateCreated":"1652801844","dateModified":"1652801844"},{"type":"update","diffId":"33362","author":"marmoute","id":"193049","dateCreated":"1651826224","dateModified":"1651826224"}],"dateCreated":"1651826224","dateModified":"1652956593","status":"Accepted"},{"id":"12623","callsign":"HG","title":"clone: use better names for temp files","author":"aalekseyev","summary":"Before this commit, the file names are \/tmp\/tmpn8smvlr8\nAfter this commit, they are more like \/tmp\/hg-clone-n8smvlr8\/00manifest.ndb3qj52v6,\nwhich makes it much clearer what these files correspond to.","testPlan":"","lineCount":"15","dependsOn":[],"reviewers":["marmoute"],"ccs":["marmoute","mercurial-patches"],"actions":[{"type":"comment","comment":">>! In D12623#193297, @aalekseyev wrote:\n> I'll remove a hardlink=True comment (which is not really worthy of a phabsend), but I don't understand the purpose of the split between (1) and (2). The only reason we're removing a directory is that we're creating it and putting temp files there.\n> Actually, a commit message could be improved...\n\nHo right, my mistake.","author":"marmoute","id":"193353","dateCreated":"1652950662","dateModified":"1652950662"},{"type":"accept","author":"marmoute","id":"193352","dateCreated":"1652950662","dateModified":"1652950662"},{"type":"update","diffId":"33404","author":"aalekseyev","id":"193310","dateCreated":"1652808529","dateModified":"1652808529"},{"type":"comment","comment":"I'll remove a hardlink=True comment (which is not really worthy of a phabsend), but I don't understand the purpose of the split between (1) and (2). The only reason we're removing a directory is that we're creating it and putting temp files there.\nActually, a commit message could be improved...","author":"aalekseyev","id":"193297","dateCreated":"1652801425","dateModified":"1652801425"},{"type":"comment","comment":"There seems to be three patches in one here :\n\n1) adding a `tryrmdir` as a last line of defence\n2) using `prefix=` in mkstemp`\n3) a comment about `hardlink=True` (that could probably we a fix to the issue here).\n\nCan you split that patch into three patches?","author":"marmoute","id":"193295","dateCreated":"1652800378","dateModified":"1652800378"},{"type":"reject","author":"marmoute","id":"193294","dateCreated":"1652800378","dateModified":"1652800378"},{"type":"update","diffId":"33399","author":"aalekseyev","id":"193243","dateCreated":"1652211048","dateModified":"1652211048"}],"dateCreated":"1652211048","dateModified":"1652950662","status":"Needs Review"},{"id":"12628","callsign":"HG","title":"worker: fix `_blockingreader.read()` to really block","author":"mharbison72","summary":"Maybe I'm missing something simple, but the help for `io.BytesIO.readinto` says:\n\n Returns number of bytes read (0 for EOF), or None if the object\n is set not to block and has no data to read.\n\nand `io.BytesIO.read` says:\n\n Return an empty bytes object at EOF.\n\nThat would seem to mean that if the _first_ internal `readinto()` of the\nnonblocking `self._wrapped` returns `None` because no data is available, the caller\nis tricked that EOF has been reached by returning an empty bytes object.","testPlan":"","lineCount":"6","dependsOn":["12627"],"reviewers":[],"ccs":["mercurial-patches"],"actions":[{"type":"comment","comment":"CI fails[1] with this series, but I think it's unrelated- its only chg, and `test-http-bad-server.t` fails for me locally in a different way, but identically with and without this series applied.\n\n```\n--- \/mnt\/c\/Users\/Matt\/hg\/tests\/test-http-bad-server.t\n+++ \/mnt\/c\/Users\/Matt\/hg\/tests\/test-http-bad-server.t.err\n@@ -42,7 +42,7 @@\n $ cat hg.pid > $DAEMON_PIDS\n\n $ hg clone http:\/\/localhost:$HGPORT\/ clone\n- abort: error: (\\$ECONNRESET\\$|\\$EADDRNOTAVAIL\\$) (re)\n+ abort: error: bad HTTP status line: ''\n [100]\n```\n\n[1] https:\/\/foss.heptapod.net\/mercurial\/mercurial-devel\/-\/jobs\/552052","author":"mharbison72","id":"193346","dateCreated":"1652892067","dateModified":"1652892067"},{"type":"update","diffId":"33408","author":"mharbison72","id":"193339","dateCreated":"1652891792","dateModified":"1652891792"}],"dateCreated":"1652891792","dateModified":"1652914579","status":"Needs Review"},{"id":"12626","callsign":"HG","title":"revlog: use %d to format int instead of %lu (issue6565)","author":"av6","summary":"The issue says gcc warns that the data types don't match. I couldn't reproduce\nthe warning locally for some reason, but this patch shouldn't break things.\nMaybe %lu was simply a copy-paste error from 6b1eae313b2f\n(https:\/\/phab.mercurial-scm.org\/D10625).","testPlan":"","lineCount":"2","dependsOn":[],"reviewers":[],"ccs":["joerg.sonnenberger","mercurial-patches"],"actions":[{"type":"comment","comment":"I think there are two issues here. The format string in line 500 doesn't match 492 and the format string in 494 doesn't either. ","author":"joerg.sonnenberger","id":"193322","dateCreated":"1652813333","dateModified":"1652813333"},{"type":"update","diffId":"33405","author":"av6","id":"193314","dateCreated":"1652811297","dateModified":"1652811297"}],"dateCreated":"1652811297","dateModified":"1652813332","status":"Needs Review"},{"id":"12622","callsign":"HG","title":"doc: use an absolute path in sys.path","author":"av6","summary":"The idea and rationale is similar to https:\/\/phab.mercurial-scm.org\/D12599\n(landed as 1b6e381521c5).","testPlan":"","lineCount":"2","dependsOn":["12621"],"reviewers":["xcintax"],"ccs":["xcintax","mercurial-patches"],"actions":[{"type":"comment","comment":"[[ https:\/\/yukcuan88.live\/ | yukcuan88 ]], [[ https:\/\/yukcuan88.live\/slots\/| Agen Judi Online Resmi 5000 ]] , [[ https:\/\/yukcuan88.live\/slots\/pragmatic-play\/ | Slot Pragmatic Gacor pakai ovo ]] , [[ https:\/\/yukcuan88.live\/slots\/cq9\/ | Slot Cq9 Terbaru Via Linkaja ]], [[ https:\/\/yukcuan88.live\/slots\/pgsoft\/ | Link PGSLOT Online Via Gopay ]], [[ https:\/\/yukcuan88.live\/slots\/joker-gaming\/ | Joker123 Deposit pulsa Tanpa Potongan ]], [[ https:\/\/yukcuan88.live\/poker\/ | Agen IdnPoker asia Via Dana ]], [[ https:\/\/yukcuan88.live\/casino\/ | BO live casino pakai gopay ]], [[ https:\/\/yukcuan88.live\/register\/ | Daftar situs judi Resmi Terpopuler ]], [[ https:\/\/yukcuan88.live\/others\/ | Taruhan adu ayam online sv388 ]], [[ https:\/\/yukcuan88.live\/fish-hunter\/ | Web Judi Tembak Ikan pulsa ]], [[ https:\/\/yukcuan88.live\/sports\/ | Bocoran Judi Bola Parlay terbaru ]],","author":"xcintax","id":"193291","dateCreated":"1652543522","dateModified":"1652543522"},{"type":"accept","author":"xcintax","id":"193290","dateCreated":"1652543522","dateModified":"1652543522"},{"type":"update","diffId":"33398","author":"av6","id":"193233","dateCreated":"1652167739","dateModified":"1652167739"}],"dateCreated":"1652167739","dateModified":"1652543522","status":"Needs Review"},{"id":"6846","callsign":"HG","title":"packaging: script the building of a MacOS installer using a custom python","author":"mharbison72","summary":"The intent here is to get away from relying on system python (which is going\naway in 10.16), so that an installer can easily be built to work on multiple\nversions of the OS. 10.9 was chosen as the minimum platform here because that's\nthe SDK needed to notarize, and also what the binary python installer targets.\nA lot of this was adapted from the script that builds the TortoiseHg DMG.\n\nThere's a useful thg customization (not duplicated here), which extends\n`sys.path` to include $HOME\/Library\/Python\/2.7\/lib\/python\/site-packages, because\nthere's no way to add to the bundled python after the app is signed. As it\nstands now, this installation won't see that, but does see\n$HOME\/.local\/lib\/python2.7\/site-packages, and the bundled `pip` will install\nthere with `--user`. It does seem like only seeing the second `--user` location\nwill get confusing, especially since the current behavior is that\n`pip install --user ...` just works for `pip` in PATH.\n\nThe prerequisite is to have python3 to run the script, and a working python2\nwith docutils installed to feed to the script. (The latter is used to build and\ninstall the documentation for Mercurial without polluting the python distro to\nbe packaged, so maybe we can use python3 there.)\n\nThe general flow is to download, build and install OpenSSL off to the side, and\nthen use that to download, build and install Python to a separate staging area.\nThe certifi package is bundled for the root certificates. I'm not an expert in\nwhat OpenSSL compilation options should be used, so if there's a way to tighten\nthings up, let me know.\n\nI don't like how the other packaging scripts assume an existing path on the\nsystem, so this uses the build directory to stage the Python and OpenSSL builds.\nThe existing system python installer stages in `build\/mercurial`, but this\nbuilds Mercurial into the staged python directory. (That path includes version\ninfo, so it shouldn't be much to add python3 support and build both at the same\ntime.) I also wasn't sure where to stash the downloads (they seem somewhat\nuseful to cache), so I stuffed them into the packages directory (which gets\nclobbered by `make clean`).\n\nTo distinguish from the system python installer (and with an eye towards\npython3), `-py2.7` is added after the Mercurial version to the file name.\nAltogether, this takes about 10 minutes to build on a 2018 Mac Mini.\n\nThere's additional followup work to do, in addition to the obvious py3 support-\nthe readme still mentions depending on system python, and this could probably be\ndriven by the makefile as a separate target. It should be trivial to sign the\nbinaries and installer, and slightly less trivial to notarize the *.pkg, but\ndefinitely doable. The files in the final *.pkg can be listed like so:\n\n pkgutil --payload-files dist\/Mercurial-*.pkg\n\nLooking at that, there's probably a bunch of junk that can be removed:\n\n - include\/\n - distutils\/tests\/\n - lib-tk\/test\/\n - ctypes\/test\/,\n - unittest\n - test\n - lib2to3\n - idle\n - pydoc\n\nI didn't see config options for that, and maybe it isn't worth it. The\ninstaller ends up around 39MB.","testPlan":"[[ https:\/\/yukcuan88.live\/ | yukcuan88 ]], [[ https:\/\/yukcuan88.live\/slots\/| Agen Judi Online Resmi 5000 ]] , [[ https:\/\/yukcuan88.live\/slots\/pragmatic-play\/ | Slot Pragmatic Gacor pakai ovo ]] , [[ https:\/\/yukcuan88.live\/slots\/cq9\/ | Slot Cq9 Terbaru Via Linkaja ]], [[ https:\/\/yukcuan88.live\/slots\/pgsoft\/ | Link PGSLOT Online Via Gopay ]], [[ https:\/\/yukcuan88.live\/slots\/joker-gaming\/ | Joker123 Deposit pulsa Tanpa Potongan ]], [[ https:\/\/yukcuan88.live\/poker\/ | Agen IdnPoker asia Via Dana ]], [[ https:\/\/yukcuan88.live\/casino\/ | BO live casino pakai gopay ]], [[ https:\/\/yukcuan88.live\/register\/ | Daftar situs judi Resmi Terpopuler ]], [[ https:\/\/yukcuan88.live\/others\/ | Taruhan adu ayam online sv388 ]], [[ https:\/\/yukcuan88.live\/fish-hunter\/ | Web Judi Tembak Ikan\u00a0pulsa ]], [[ https:\/\/yukcuan88.live\/sports\/ | Bocoran Judi\u00a0Bola Parlay terbaru ]],","lineCount":"364","dependsOn":[],"reviewers":[],"ccs":["xcintax","mercurial-patches","indygreg","marmoute","mercurial-devel"],"actions":[{"type":"comment","comment":"[[ https:\/\/yukcuan88.live\/ | yukcuan88 ]], [[ https:\/\/yukcuan88.live\/slots\/| Agen Judi Online Resmi 5000 ]] , [[ https:\/\/yukcuan88.live\/slots\/pragmatic-play\/ | Slot Pragmatic Gacor pakai ovo ]] , [[ https:\/\/yukcuan88.live\/slots\/cq9\/ | Slot Cq9 Terbaru Via Linkaja ]], [[ https:\/\/yukcuan88.live\/slots\/pgsoft\/ | Link PGSLOT Online Via Gopay ]], [[ https:\/\/yukcuan88.live\/slots\/joker-gaming\/ | Joker123 Deposit pulsa Tanpa Potongan ]], [[ https:\/\/yukcuan88.live\/poker\/ | Agen IdnPoker asia Via Dana ]], [[ https:\/\/yukcuan88.live\/casino\/ | BO live casino pakai gopay ]], [[ https:\/\/yukcuan88.live\/register\/ | Daftar situs judi Resmi Terpopuler ]], [[ https:\/\/yukcuan88.live\/others\/ | Taruhan adu ayam online sv388 ]], [[ https:\/\/yukcuan88.live\/fish-hunter\/ | Web Judi Tembak Ikan pulsa ]], [[ https:\/\/yukcuan88.live\/sports\/ | Bocoran Judi Bola Parlay terbaru ]],","author":"xcintax","id":"193288","dateCreated":"1652543483","dateModified":"1652543483"},{"type":"comment","comment":">>! In D6846#126171, @marmoute wrote:\n> So as I understand this is not ready to land and should be moved to change-requested (or change planned), right ?\n\nYeah, I'll move this out of the way, and can abandon it when PyOxidizer builds are in place.","author":"mharbison72","id":"126173","dateCreated":"1587149777","dateModified":"1587149777"},{"type":"plan-changes","author":"mharbison72","id":"126172","dateCreated":"1587149777","dateModified":"1587149777"},{"type":"comment","comment":"So as I understand this is not ready to land and should be moved to change-requested (or change planned), right ?","author":"marmoute","id":"126171","dateCreated":"1587148771","dateModified":"1587148771"},{"type":"comment","comment":">>! In D6846#124054, @marmoute wrote:\n> What's the status of this ? @mharbison72 id the linking problem got solved ?\n\nI've been too busy to get back to this, and probably won't for the short term, anyway.\n\nIt would probably also be a good to have a general idea when we drop py2 completely. I'd be content leaving py2 around for awhile for various reasons, but I don't want to sink a bunch of time into something that lasts for one release. (I think a PyOxidizer build would end up being a lot different looking than this.)","author":"mharbison72","id":"124250","dateCreated":"1584759006","dateModified":"1584759006"},{"type":"comment","comment":"What's the status of this ? @mharbison72 id the linking problem got solved ?","author":"marmoute","id":"124054","dateCreated":"1584659831","dateModified":"1584659831"},{"type":"inline","comment":"From the scripts used to build TortoiseHg on Mac, and the OpenSSL wiki:\n\nhttps:\/\/bitbucket.org\/Weeds2000\/tortoisehg-osx-build-scripts\/src\/e459bb439730d7e7e3a4b8c474f74aab164d6c9f\/toolchain\/receipts\/openssl.sh#lines-41\n\nhttps:\/\/wiki.openssl.org\/index.php\/Compilation_and_Installation#OS_X","replyTo":"120515","isNewFile":"1","line":"54","lineLength":"0","path":"contrib\/packaging\/hgpackaging\/python.py","diffId":"16526","author":"mharbison72","id":"120558","dateCreated":"1581526775","dateModified":"1581526775"},{"type":"inline","comment":"The original shebang line was much longer, so after writing it out with the shorter one, I think this was meant to trim the file. too the proper content.","replyTo":"120517","isNewFile":"1","line":"170","lineLength":"0","path":"contrib\/packaging\/macosx\/build.py","diffId":"16526","author":"mharbison72","id":"120557","dateCreated":"1581526775","dateModified":"1581526775"},{"type":"comment","comment":">>! In D6846#120513, @indygreg wrote:\n> macOS supports a `@loader_path` and related magic tokens in rpath to load libraries relative to the current binary. See e.g. https:\/\/blogs.oracle.com\/dipol\/dynamic-libraries,-rpath,-and-mac-os and https:\/\/medium.com\/@donblas\/fun-with-rpath-otool-and-install-name-tool-e3e41ae86172 for examples.\n\nI saw those, thanks. I guess what's confusing is I don't see RPATH being configured when building OpenSSL for the TortoiseHg build, nor do I see it being overwritten when running py2app. I also interpreted this to mean that is should be automatic on Mac, but I guess not:\n\nhttps:\/\/wiki.openssl.org\/index.php\/Compilation_and_Installation#Using_RPATHs","author":"mharbison72","id":"120556","dateCreated":"1581526775","dateModified":"1581526775"},{"type":"inline","comment":"`fp.truncate()`?","replyTo":null,"isNewFile":"1","line":"170","lineLength":"0","path":"contrib\/packaging\/macosx\/build.py","diffId":"16526","author":"indygreg","id":"120517","dateCreated":"1581476182","dateModified":"1581476182"},{"type":"inline","comment":"I _think_ we also want `--enable-lto` for more speed wins.","replyTo":null,"isNewFile":"1","line":"120","lineLength":"0","path":"contrib\/packaging\/hgpackaging\/python.py","diffId":"16526","author":"indygreg","id":"120516","dateCreated":"1581476182","dateModified":"1581476182"},{"type":"inline","comment":"Where did you get this line and `enable-cms` from?","replyTo":null,"isNewFile":"1","line":"54","lineLength":"0","path":"contrib\/packaging\/hgpackaging\/python.py","diffId":"16526","author":"indygreg","id":"120515","dateCreated":"1581476182","dateModified":"1581476182"},{"type":"inline","comment":"1.0.2u is out and should be used.","replyTo":null,"isNewFile":"1","line":"29","lineLength":"0","path":"contrib\/packaging\/hgpackaging\/downloads.py","diffId":"16526","author":"indygreg","id":"120514","dateCreated":"1581476182","dateModified":"1581476182"},{"type":"comment","comment":"macOS supports a `@loader_path` and related magic tokens in rpath to load libraries relative to the current binary. See e.g. https:\/\/blogs.oracle.com\/dipol\/dynamic-libraries,-rpath,-and-mac-os and https:\/\/medium.com\/@donblas\/fun-with-rpath-otool-and-install-name-tool-e3e41ae86172 for examples.","author":"indygreg","id":"120513","dateCreated":"1581475710","dateModified":"1581475710"},{"type":"comment","comment":"Ha, ok.","author":"marmoute","id":"119491","dateCreated":"1580979783","dateModified":"1580979783"},{"type":"comment","comment":">>! In D6846#119328, @marmoute wrote:\n> are we talking about python library or compiled library ? Go you have any \"empty\" item in the various PATH used for the build ?\n\nSee https:\/\/phab.mercurial-scm.org\/D6846#100512.\n\nI'm not sure what you mean about empty items. The build directory is out of the way, not on PATH. It's just that `_ssl.so` wants to load OpenSSL libraries from the path where they were built. It actually works fine after installing- until you do a `make clean`, which is how I noticed the problem.","author":"mharbison72","id":"119482","dateCreated":"1580956098","dateModified":"1580956098"},{"type":"comment","comment":"are we talking about python library or compiled library ? Go you have any \"empty\" item in the various PATH used for the build ?","author":"marmoute","id":"119328","dateCreated":"1580918617","dateModified":"1580918617"},{"type":"comment","comment":">>! In D6846#118733, @marmoute wrote:\n> What's the latest with this diff ? It seems to still be a work in progress. Should it be in the \"need-review\" state?\n\nThe hangup here is that the installed code seems to want to look in the path where it was built to load libraries. I have no idea why. It would be good if somebody figured out why, because I have a similar problem with the thg build on Mac. (But unlike here, that's not fatal because it falls back to a library inside the bundle.)\n\nMy thought with this was to be able to build an official py2 installer that worked on more than the very latest platform. But I also thought that we would hang on to py2 for awhile. If we're not, then this probably isn't worth pursuing, assuming PyOxidizer works out on OS X (so far, so good). I'm not so excited about dropping py2 because of the amount of work still needed on hg on Windows, thg on Windows and Mac, and the packaging on both. But 10.16 will remove all builtin python, so something will probably need to be done one way or the other by September or so.","author":"mharbison72","id":"118786","dateCreated":"1580448255","dateModified":"1580448255"},{"type":"comment","comment":"What's the latest with this diff ? It seems to still be a work in progress. Should it be in the \"need-review\" state?","author":"marmoute","id":"118733","dateCreated":"1580408474","dateModified":"1580408474"},{"type":"comment","comment":">>! In D6846#100478, @mharbison72 wrote:\n> This seems to work (though the shebang line hack is painful)- until the original python build directory is deleted. Then a lot of things complain about unsupported hash type for md5 and sha{1,224,256,384,512}. Other modules like `json` can be imported with the installed python executable. I grepped around for the build directory, and it is in a bunch of *.so files (though this could be `__FILE__` for all I know). Any ideas?\n\nSo, the problem here is that openssl libraries are being built and installed with the temporary install path, and the `_ssl.so` module is expecting to find them there. I tried a custom Setup.local that statically links `_ssl.so` against openssl before configuring python, but the build summary said dependencies were missing to build `_ssl` (among other things). For some reason, the resulting build still seemed to be able to talk to https servers. `help(_ssl)` said it was builtin, whereas `help(_ssl)` on the original build mentioned openssl (IIRC).\n\nThe `_ssl.so` module in the thg app has `@executable_path` in the library name, so that's why that works. I also tried messing with `@rpath`, but I can't get that working either. I'm not sure what else to try.","author":"mharbison72","id":"100512","dateCreated":"1568414255","dateModified":"1568414255"},{"type":"comment","comment":"This seems to work (though the shebang line hack is painful)- until the original python build directory is deleted. Then a lot of things complain about unsupported hash type for md5 and sha{1,224,256,384,512}. Other modules like `json` can be imported with the installed python executable. I grepped around for the build directory, and it is in a bunch of *.so files (though this could be `__FILE__` for all I know). Any ideas?","author":"mharbison72","id":"100478","dateCreated":"1568327294","dateModified":"1568327294"},{"type":"update","diffId":"16526","author":"mharbison72","id":"100472","dateCreated":"1568326880","dateModified":"1568326880"}],"dateCreated":"1568326880","dateModified":"1652543483","status":"Changes Planned"},{"id":"12621","callsign":"HG","title":"check-py3-compat: use an absolute path in sys.path","author":"av6","summary":"The idea and rationale is similar to https:\/\/phab.mercurial-scm.org\/D12599\n(landed as 1b6e381521c5).","testPlan":"","lineCount":"2","dependsOn":[],"reviewers":[],"ccs":["mercurial-patches"],"actions":[{"type":"update","diffId":"33397","author":"av6","id":"193225","dateCreated":"1652167731","dateModified":"1652167731"}],"dateCreated":"1652167731","dateModified":"1652167739","status":"Needs Review"},{"id":"12557","callsign":"HG","title":"windows: fix stdio with py2exe and py3","author":"mharbison72","summary":"** DO NOT QUEUE THIS **\n\nI have no idea how this is supposed to be fixed for real, but it's likely\nrelated to the comment above where stdout is set about maybe needing a silly\nwrapper. PEP 528[1] talks about not assuming the encoding of sys.stdout.buffer,\nbut I thought the whole point of always using bytes was to avoid encoding.\n\nThis hack allows TortoiseHg to work when built with py2exe on py3, by avoiding\nthis:\n\n #!python\n ** Mercurial version (6.1.1+hg216.d8b5fd0ab640local20220412). TortoiseHg version (6.1.1+26-204092cabbee)\n ** Command: --nofork workbench\n ** CWD: C:\\Users\\Administrator\\Desktop\n ** Encoding: cp1252\n ** Extensions loaded: absorb, strip, tortoisehg.util.configitems\n ** Python version: 3.9.12 (tags\/v3.9.12:b28265d, Mar 23 2022, 23:52:46) [MSC v.1929 64 bit (AMD64)]\n ** Windows version: sys.getwindowsversion(major=6, minor=2, build=9200, platform=2, service_pack='')\n ** Processor architecture: x64\n ** Qt-5.15.2 PyQt-5.15.6 QScintilla-2.13.1\n Traceback (most recent call last):\n File \"tortoisehg\\hgqt\\repotab.pyc\", line 355, in _onCurrentTabChanged\n File \"tortoisehg\\hgqt\\repotab.pyc\", line 406, in _createRepoWidget\n File \"tortoisehg\\hgqt\\repowidget.pyc\", line 228, in __init__\n File \"tortoisehg\\hgqt\\repowidget.pyc\", line 260, in setupUi\n File \"tortoisehg\\hgqt\\repofilter.pyc\", line 264, in __init__\n File \"tortoisehg\\hgqt\\repofilter.pyc\", line 554, in refresh\n File \"tortoisehg\\hgqt\\repofilter.pyc\", line 491, in _updateBranchFilter\n File \"tortoisehg\\util\\hglib.pyc\", line 237, in namedbranches\n File \"mercurial\\localrepo.pyc\", line 2154, in branchmap\n File \"mercurial\\branchmap.pyc\", line 72, in __getitem__\n File \"mercurial\\branchmap.pyc\", line 81, in updatecache\n File \"mercurial\\repoview.pyc\", line 421, in changelog\n File \"mercurial\\repoview.pyc\", line 248, in filterrevs\n File \"mercurial\\repoview.pyc\", line 104, in computehidden\n File \"mercurial\\repoview.pyc\", line 43, in hideablerevs\n File \"mercurial\\obsolete.pyc\", line 911, in getrevs\n File \"mercurial\\localrepo.pyc\", line 118, in __get__\n File \"mercurial\\scmutil.pyc\", line 1709, in __get__\n File \"mercurial\\localrepo.pyc\", line 1723, in obsstore\n File \"mercurial\\obsolete.pyc\", line 817, in makestore\n File \"mercurial\\ui.pyc\", line 1855, in warn\n File \"mercurial\\ui.pyc\", line 1330, in _writemsg\n File \"mercurial\\ui.pyc\", line 2282, in _writemsgwith\n File \"mercurial\\ui.pyc\", line 1273, in _write\n File \"mercurial\\ui.pyc\", line 1298, in _writenobuf\n File \"mercurial\\windows.pyc\", line 240, in write\n File \"mercurial\\utils\\procutil.pyc\", line 114, in write\n File \"boot_common.py\", line 74, in write\n TypeError: write() argument must be str, not memoryview\n\n[1] https:\/\/peps.python.org\/pep-0528\/","testPlan":"","lineCount":"10","dependsOn":[],"reviewers":[],"ccs":["mjacob","mercurial-patches"],"actions":[{"type":"comment","comment":">>! In D12557#193221, @mjacob wrote:\n> I\u2019m a bit confused. Shouldn\u2019t it fail already on the line `stdout = _make_write_all(sys.stdout.buffer)` because `sys.stdout` has no attribute `buffer`?\n\nI'm completely baffled. The change to `_make_write_all(getattr(sys.stderr, 'buffer', sys.stderr))` came from someone else who helped with the initial installer work. I only applied it after I ran into the exception myself. I don't see any issue running `thg --nofork` from either the staging area, or from an actual installation. I'm 99.99% sure that the `--nofork` way was how I was running this in the beginning, because there were so many buried exceptions on startup.\n\nThat said, when I run `thgw.exe` with the original `sys.stderr.buffer` line (i.e. a clean copy of hg a932cad26d37), I get this in `%PROGRAMFILES%\\thgw.log` (after running as admin, because it doesn't normally have permission to write a file there):\n\n```\nTraceback (most recent call last):\n File \"thg\", line 91, in <module>\n File \"<frozen importlib._bootstrap>\", line 1007, in _find_and_load\n File \"<frozen importlib._bootstrap>\", line 986, in _find_and_load_unlocked\n File \"<frozen importlib._bootstrap>\", line 664, in _load_unlocked\n File \"<frozen importlib._bootstrap>\", line 627, in _load_backward_compatible\n File \"<frozen zipimport>\", line 259, in load_module\n File \"tortoisehg\\hgqt\\run.pyc\", line 17, in <module>\n File \"<frozen importlib._bootstrap>\", line 1007, in _find_and_load\n File \"<frozen importlib._bootstrap>\", line 986, in _find_and_load_unlocked\n File \"<frozen importlib._bootstrap>\", line 664, in _load_unlocked\n File \"<frozen importlib._bootstrap>\", line 627, in _load_backward_compatible\n File \"<frozen zipimport>\", line 259, in load_module\n File \"mercurial\\cmdutil.pyc\", line 27, in <module>\n File \"<frozen importlib._bootstrap>\", line 1007, in _find_and_load\n File \"<frozen importlib._bootstrap>\", line 986, in _find_and_load_unlocked\n File \"<frozen importlib._bootstrap>\", line 664, in _load_unlocked\n File \"<frozen importlib._bootstrap>\", line 627, in _load_backward_compatible\n File \"<frozen zipimport>\", line 259, in load_module\n File \"mercurial\\bookmarks.pyc\", line 19, in <module>\n File \"<frozen importlib._bootstrap>\", line 1007, in _find_and_load\n File \"<frozen importlib._bootstrap>\", line 986, in _find_and_load_unlocked\n File \"<frozen importlib._bootstrap>\", line 664, in _load_unlocked\n File \"<frozen importlib._bootstrap>\", line 627, in _load_backward_compatible\n File \"<frozen zipimport>\", line 259, in load_module\n File \"mercurial\\obsutil.pyc\", line 16, in <module>\n File \"<frozen importlib._bootstrap>\", line 1007, in _find_and_load\n File \"<frozen importlib._bootstrap>\", line 986, in _find_and_load_unlocked\n File \"<frozen importlib._bootstrap>\", line 664, in _load_unlocked\n File \"<frozen importlib._bootstrap>\", line 627, in _load_backward_compatible\n File \"<frozen zipimport>\", line 259, in load_module\n File \"mercurial\\diffutil.pyc\", line 13, in <module>\n File \"<frozen importlib._bootstrap>\", line 1007, in _find_and_load\n File \"<frozen importlib._bootstrap>\", line 986, in _find_and_load_unlocked\n File \"<frozen importlib._bootstrap>\", line 664, in _load_unlocked\n File \"<frozen importlib._bootstrap>\", line 627, in _load_backward_compatible\n File \"<frozen zipimport>\", line 259, in load_module\n File \"mercurial\\mdiff.pyc\", line 18, in <module>\n File \"<frozen importlib._bootstrap>\", line 1007, in _find_and_load\n File \"<frozen importlib._bootstrap>\", line 986, in _find_and_load_unlocked\n File \"<frozen importlib._bootstrap>\", line 664, in _load_unlocked\n File \"<frozen importlib._bootstrap>\", line 627, in _load_backward_compatible\n File \"<frozen zipimport>\", line 259, in load_module\n File \"mercurial\\util.pyc\", line 54, in <module>\n File \"<frozen importlib._bootstrap>\", line 1007, in _find_and_load\n File \"<frozen importlib._bootstrap>\", line 986, in _find_and_load_unlocked\n File \"<frozen importlib._bootstrap>\", line 664, in _load_unlocked\n File \"<frozen importlib._bootstrap>\", line 627, in _load_backward_compatible\n File \"<frozen zipimport>\", line 259, in load_module\n File \"mercurial\\utils\\procutil.pyc\", line 150, in <module>\nAttributeError: 'Blackhole' object has no attribute 'buffer'\n```","author":"mharbison72","id":"193223","dateCreated":"1652144160","dateModified":"1652144160"},{"type":"comment","comment":"I\u2019m a bit confused. Shouldn\u2019t it fail already on the line `stdout = _make_write_all(sys.stdout.buffer)` because `sys.stdout` has no attribute `buffer`?","author":"mjacob","id":"193221","dateCreated":"1652126761","dateModified":"1652126761"},{"type":"comment","comment":"The exception happened before this change- py2exe apparently wants str based stdio. The weird thing is when I retested by throwing this whole patch away, I can't recreate the issue- even by disabling evolve to get what I assume is the warning message here about obsolete markers being found without the feature being enabled.","author":"mharbison72","id":"193220","dateCreated":"1652126508","dateModified":"1652126508"},{"type":"comment","comment":"Does the exception in the description happen with the code before this patch or only if replacing `sys.stderr.buffer` by `getattr(sys.stderr, 'buffer', sys.stderr)`?","author":"mjacob","id":"193127","dateCreated":"1651984939","dateModified":"1651984939"},{"type":"update","diffId":"33172","author":"mharbison72","id":"192047","dateCreated":"1649890090","dateModified":"1649890090"}],"dateCreated":"1649890090","dateModified":"1652144160","status":"Needs Review"},{"id":"12494","callsign":"HG","title":"[RFC] rust-revlog: create nodemap on the fly if it's not persisted","author":"martinvonz","summary":"We can create a nodemap in memory when there isn't a persistent\none. When listing all commits in the hg repo, it sped up the\nequivalent of `hg log -T '{node}\\n' --hidden` (but run with my hobby\nproject's hg backend) from 123 s to 2.55 s.\n\nWhat do we actually want to do here? Calculate the map after we've\ndone a few O(n) node-to-rev requests? I think that's what the C\nimplementation does.","testPlan":"","lineCount":"27","dependsOn":["12424"],"reviewers":[],"ccs":["marmoute","Alphare","mercurial-patches"],"actions":[{"type":"update","diffId":"33396","author":"martinvonz","id":"193219","dateCreated":"1652123619","dateModified":"1652123619"},{"type":"update","diffId":"33191","author":"martinvonz","id":"192210","dateCreated":"1650088033","dateModified":"1650088033"},{"type":"update","diffId":"33158","author":"martinvonz","id":"191977","dateCreated":"1649855436","dateModified":"1649855436"},{"type":"comment","comment":">>! In D12494#191335, @marmoute wrote:\n> So this is not a problem for mercurial as is. Improving this in general is still a good idea.\n\nAs mentioned in the commit message, it was when using my hobby project's hg backend. That's https:\/\/github.com\/martinvonz\/jj\/commit\/be1fd35afe098db0d44e31499cfccf2a64ab217d\n","author":"martinvonz","id":"191336","dateCreated":"1649766862","dateModified":"1649766862"},{"type":"comment","comment":"Note that this should not be a practical issue right now, as `rhg` is not accessing multiple revision yet and `hg` use an intermediate layer that use the C caching if persistent nodemap is missing.\nSo this is not a problem for mercurial as is. Improving this in general is still a good idea.","author":"marmoute","id":"191335","dateCreated":"1649756700","dateModified":"1649759310"},{"type":"inline","comment":"`.expect(\"node should exist in index\")`","replyTo":null,"isNewFile":"1","line":"128","lineLength":"0","path":"rust\/hg-core\/src\/revlog\/revlog.rs","diffId":"33005","author":"Alphare","id":"191306","dateCreated":"1649753469","dateModified":"1649753469"},{"type":"comment","comment":"The C implementation indeed builds the nodemap after 3 misses. We will probably want to do the same thing here, however the Rust implementation will require more work because we don't want our getter methods to all take `&mut self`.\n\nFor now, this looks good. Small revlogs will not be affected and large operations on the changelog\/manifest call for a persistent nodemap anyway, so why not. If we end up needing to do something more clever down the line (like I suspect we will, given revlogv2 at least), we will think about how to organize our types to encode that API in a clear fashion... or just use interior mutability for the nodemap.","author":"Alphare","id":"191305","dateCreated":"1649753469","dateModified":"1649753469"},{"type":"update","diffId":"33005","author":"martinvonz","id":"191286","dateCreated":"1649693229","dateModified":"1649693229"}],"dateCreated":"1649693229","dateModified":"1652123619","status":"Needs Review"},{"id":"12424","callsign":"HG","title":"rust: upgrade zstd from 0.5.3 to 0.11.1","author":"martinvonz","summary":"I'd like to experiment with an hg backend for my hobby project and it\nuses a newer zstd version. Seems good to stay up do date anyway.","testPlan":"","lineCount":"35","dependsOn":[],"reviewers":["Alphare"],"ccs":["indygreg","spectral","Alphare","mercurial-patches"],"actions":[{"type":"update","diffId":"33395","author":"martinvonz","id":"193218","dateCreated":"1652123618","dateModified":"1652123618"},{"type":"update","diffId":"33373","author":"martinvonz","id":"193161","dateCreated":"1652110944","dateModified":"1652110944"},{"type":"comment","comment":"I don't want to block this too much if I'm about the only one who cares enough about this. I don't like raising the minimum version of anything without a good reason because it breaks lots of things (including compatibility with downstream crates, not just with distros), but not being able to upgrade our own dependencies might be good reason enough. It's kind of a vicious circle, but I get it.\n\nI will send an email to the packaging mailing list to ask them what a change in policy (to say, move to the Debian testing version) would change for them if anything, and make our decision from there even if it may go against their wishes.","author":"Alphare","id":"192755","dateCreated":"1650876532","dateModified":"1650876532"},{"type":"update","diffId":"33190","author":"martinvonz","id":"192209","dateCreated":"1650088033","dateModified":"1650088033"},{"type":"comment","comment":"I think it is pretty ridiculous that Linux distributions artificially constrain the forward progress of entire language ecosystems by moving at a glacial pace. Python version compatibility is already problematic for Mercurial and now we're throwing Rust into the mix. And that is arguably worse since Python does major releases once per year versus Rust's 6 week release cadence.\n\nGiven that Rust is an optional dependency for Mercurial, I'd like to think there is some room to consider more aggressively upgrading the minimal supported Rust version. If enough projects start doing this, I suspect the distros will eventually realize their current practices aren't in the best interests of their end-users and they'll come around to supporting more modern Rust so they can package the applications their users demand.","author":"indygreg","id":"192131","dateCreated":"1649979575","dateModified":"1649979575"},{"type":"update","diffId":"33157","author":"martinvonz","id":"191976","dateCreated":"1649855435","dateModified":"1649855435"},{"type":"comment","comment":">>! In D12424#191195, @spectral wrote:\n\n> I'm curious about this. This is a compiled language - you have to ensure that you can *run* on a debian stable machine, but I don't see a strong reason to require that you can *build* on a debian stable machine?\n\nThe point of this (very annoying, I admit) limitation to Debian Stable *is* to allow its users to build a more recent Mercurial while trusting the toolchain of their distro, i.e. without relying on rustup and other prebuilt binaries. A CI runner is also a good example of such a \"user\".\n\nWhether we choose to purposely break that workflow because we want a more recent compiler is up for debate, I think we can afford to stay behind to ease compatibility. Lastly, we may have downstream crates in the future, like the planned `hgignore` crate could be used by `ripgrep` and the like and we would need to be pretty backwards compatible for this.\n","author":"Alphare","id":"191303","dateCreated":"1649752365","dateModified":"1649752365"},{"type":"update","diffId":"32992","author":"martinvonz","id":"191215","dateCreated":"1649482561","dateModified":"1649482561"},{"type":"update","diffId":"32987","author":"martinvonz","id":"191196","dateCreated":"1649447842","dateModified":"1649447842"},{"type":"comment","comment":">>! In D12424#190106, @Alphare wrote:\n> Unfortunately, `zstd > 0.5.3` does not support our minimum version of Rust which is 1.48.0. I'd already tried updating, but this'll have to wait until Debian stable updates (or someone adds back backwards compat, which I doubt).\n\nI'm curious about this. This is a compiled language - you have to ensure that you can *run* on a debian stable machine, but I don't see a strong reason to require that you can *build* on a debian stable machine? Especially since rust lets you have user-directory installations of rustc? The only reason to require this is if you expect that debian stable will take a new version of hg, which seems unlikely (they'll backport any fixes, but won't just willy nilly upgrade hg from 5.6.1 to 6.1 or 6.2 for any reason). So I think you shouldn't hold back to require debian stable can build the package, though it should be able to build on whatever rust comes with debian testing, for obvious reasons. This appears to currently be 1.57.","author":"spectral","id":"191195","dateCreated":"1649446605","dateModified":"1649446605"},{"type":"comment","comment":"Unfortunately, `zstd > 0.5.3` does not support our minimum version of Rust which is 1.48.0. I'd already tried updating, but this'll have to wait until Debian stable updates (or someone adds back backwards compat, which I doubt).","author":"Alphare","id":"190106","dateCreated":"1648804507","dateModified":"1648804507"},{"type":"reject","author":"Alphare","id":"190105","dateCreated":"1648804507","dateModified":"1648804507"},{"type":"update","diffId":"32738","author":"martinvonz","id":"190074","dateCreated":"1648751287","dateModified":"1648751287"}],"dateCreated":"1648751287","dateModified":"1652123618","status":"Needs Review"},{"id":"12620","callsign":"HG","title":"tests: make sure .js files stay in ASCII encoding (issue6559)","author":"av6","summary":"","testPlan":"","lineCount":"26","dependsOn":[],"reviewers":[],"ccs":["mercurial-patches"],"actions":[{"type":"update","diffId":"33394","author":"av6","id":"193214","dateCreated":"1652116034","dateModified":"1652116034"}],"dateCreated":"1652116034","dateModified":"1652116034","status":"Needs Review"},{"id":"12603","callsign":"HG","title":"diff: graduate merge diffs from experimental and add to tweakdefaults","author":"durin42","summary":"I've been using this functionality for two years without incident and\nit's been outstanding. In my opinion it's time to both remove the\nexperimental warning label and move this straight into tweakdefaults.","testPlan":"","lineCount":"3","dependsOn":[],"reviewers":["martinvonz"],"ccs":["mharbison72","martinvonz","mercurial-patches"],"actions":[{"type":"comment","comment":">>! In D12603#193012, @durin42 wrote:\n>>>! In D12603#193005, @martinvonz wrote:\n>> I agree, except that I've seen it crash sometimes. I wrote a little script to find such cases now. Here's an example: `hg diff --change 7c2921a6`. So we need to fix that first. Sorry I never bothered to report a bug for it.\n> \n> That doesn't crash for me! Even `HGRCPATH=\/dev\/null hg diff --change 7c2921a6 --config diff.merge=1` works...can you try and figure out why you're seeing a crash?\n\nIt wasn't easy to find, but I've finally isolated it to this:\n\n```\nHGRCPATH= hg diff --change 7c2921a6 --config diff.merge=1 --config experimental.copies.read-from=changeset-only\n```\n","author":"martinvonz","id":"193027","dateCreated":"1651723715","dateModified":"1651723715"},{"type":"comment","comment":"Do we still have the problem of not being able to individually disable options enabled by tweakdefaults? I think there was a bug about it that probably got auto-closed.","author":"mharbison72","id":"193015","dateCreated":"1651690880","dateModified":"1651690880"},{"type":"comment","comment":">>! In D12603#193005, @martinvonz wrote:\n> I agree, except that I've seen it crash sometimes. I wrote a little script to find such cases now. Here's an example: `hg diff --change 7c2921a6`. So we need to fix that first. Sorry I never bothered to report a bug for it.\n\nThat doesn't crash for me! Even `HGRCPATH=\/dev\/null hg diff --change 7c2921a6 --config diff.merge=1` works...can you try and figure out why you're seeing a crash?","author":"durin42","id":"193012","dateCreated":"1651684208","dateModified":"1651684208"},{"type":"comment","comment":"I agree, except that I've seen it crash sometimes. I wrote a little script to find such cases now. Here's an example: `hg diff --change 7c2921a6`. So we need to fix that first. Sorry I never bothered to report a bug for it.","author":"martinvonz","id":"193005","dateCreated":"1651682267","dateModified":"1651682267"},{"type":"reject","author":"martinvonz","id":"193004","dateCreated":"1651682267","dateModified":"1651682267"},{"type":"update","diffId":"33353","author":"durin42","id":"192998","dateCreated":"1651681150","dateModified":"1651681150"}],"dateCreated":"1651681150","dateModified":"1651723715","status":"Needs Revision"},{"id":"12600","callsign":"HG","title":"Enforce narrowacl in narrow_widen","author":"idlsoft","summary":"","testPlan":"","lineCount":"42","dependsOn":[],"reviewers":["durin42","martinvonz"],"ccs":["mercurial-patches"],"actions":[{"type":"update","diffId":"33333","author":"idlsoft","id":"192915","dateCreated":"1651629960","dateModified":"1651629960"}],"dateCreated":"1651629960","dateModified":"1651629960","status":"Needs Review"},{"id":"12587","callsign":"HG","title":"color: support the NO_COLOR environment variable","author":"Alphare","summary":"The https:\/\/no-color.org initiative is a good idea, it's easy to support. It\neven explicitly lists Mercurial as one of the programs that don't support it.","testPlan":"","lineCount":"11","dependsOn":[],"reviewers":[],"ccs":["av6","mercurial-patches"],"actions":[{"type":"comment","comment":"I like seeing support of community standards that underline how one size^W default configuration doesn't fit all, so I think this is a great feature. Hopefully it won't be too hard to implement.\n\n> explicitly lists Mercurial as one of the programs that don't support it\nOuch.","author":"av6","id":"192885","dateCreated":"1651486612","dateModified":"1651486612"},{"type":"comment","comment":"Wait, this is not the right precedence, it should honor config.","author":"Alphare","id":"192798","dateCreated":"1650969048","dateModified":"1650969048"},{"type":"plan-changes","author":"Alphare","id":"192797","dateCreated":"1650969048","dateModified":"1650969048"},{"type":"update","diffId":"33313","author":"Alphare","id":"192792","dateCreated":"1650968972","dateModified":"1650968972"}],"dateCreated":"1650968972","dateModified":"1651486612","status":"Changes Planned"},{"id":"12583","callsign":"HG","title":"iblt: prototype for setdiscovery","author":"joerg.sonnenberger","summary":"","testPlan":"","lineCount":"416","dependsOn":[],"reviewers":[],"ccs":["mercurial-patches"],"actions":[{"type":"comment","comment":"This is a proof-of-concept still, not for actual merge.","author":"joerg.sonnenberger","id":"192730","dateCreated":"1650583641","dateModified":"1650583641"},{"type":"update","diffId":"33303","author":"joerg.sonnenberger","id":"192726","dateCreated":"1650583450","dateModified":"1650583450"}],"dateCreated":"1650583450","dateModified":"1650583641","status":"Needs Review"},{"id":"12485","callsign":"HG","title":"help: add amend to basic help page","author":"czom","summary":"If you run just \"hg\", unamend is on the list, but amend is not. This change adds amend to the list to be consistent.","testPlan":"","lineCount":"1","dependsOn":[],"reviewers":[],"ccs":["Alphare","marmoute","mercurial-patches"],"actions":[{"type":"comment","comment":"Not sure if `[un]amend` is to be considered \"basic\", but aside from the semantics, I think it helps with discoverability of Evolution. The actual divergence between core and `evolve` is a separate issue that shouldn't be the end-user's problem. @marmoute thoughts?","author":"Alphare","id":"192373","dateCreated":"1650371885","dateModified":"1650371885"},{"type":"comment","comment":"IMO the list is not too long yet, and it's fine to have one more (would have helped me back then). But I don't have a strong preference.","author":"czom","id":"190930","dateCreated":"1649424491","dateModified":"1649424491"},{"type":"comment","comment":"should we move `unamend` away from the basic list instead ?","author":"marmoute","id":"190915","dateCreated":"1649418025","dateModified":"1649418025"},{"type":"update","diffId":"32876","author":"czom","id":"190855","dateCreated":"1649412835","dateModified":"1649412835"}],"dateCreated":"1649412835","dateModified":"1650371885","status":"Needs Review"},{"id":"12418","callsign":"HG","title":"copies: add config to preserve old copies (issue5457)","author":"martinvonz","summary":"The scenario in issue 5457 gets reported every now and then by our\nusers (Google developers). This patch adds a fix for it by preserving\nexisting copies even if the source file no longer exists. That's a bit\nof hack, but it's effective and much simpler than the other\nalternatives we've considered (such as storing the copy information in\nobsmarkers, which would mean that copy tracing would have to follow\nboth graphs).\n\nThe fix only works when copies are stored in changeset extras or\nsidedata because the filelog record needs to have the old file nodeid,\nwhich doesn't exist in the parent manifest.","testPlan":"","lineCount":"20","dependsOn":["12417"],"reviewers":[],"ccs":["Alphare","marmoute","mercurial-patches"],"actions":[{"type":"comment","comment":"As a knee-jerk reaction to the commit message only, I'd say that I am *very* uncomfortable essentially keeping broken data around. I will need to think about this when I have more time than today, I wanted to say something soon so you wouldn't think this went overlooked.","author":"Alphare","id":"190442","dateCreated":"1649240936","dateModified":"1649240936"},{"type":"comment","comment":">>! In D12418#190140, @marmoute wrote:\n> What happens to the old (now invalid) value after the rebase ?\n\nWhich \"value\" do you mean? The copy information is stored in the amended commit, so it's not affected by the rebase. It will remain there after commits are rebased on top as usual.","author":"martinvonz","id":"190231","dateCreated":"1649091376","dateModified":"1649091376"},{"type":"comment","comment":"What happens to the old (now invalid) value after the rebase ?","author":"marmoute","id":"190140","dateCreated":"1648920581","dateModified":"1648920581"},{"type":"update","diffId":"32732","author":"martinvonz","id":"190025","dateCreated":"1648613938","dateModified":"1648613938"}],"dateCreated":"1648613938","dateModified":"1649240936","status":"Needs Review"},{"id":"12417","callsign":"HG","title":"tests: add test for rebasing commit after amending rename into parent","author":"martinvonz","summary":"This adds a test for\nhttps:\/\/bz.mercurial-scm.org\/show_bug.cgi?id=5457.","testPlan":"","lineCount":"31","dependsOn":[],"reviewers":[],"ccs":["mercurial-patches"],"actions":[{"type":"update","diffId":"32731","author":"martinvonz","id":"190019","dateCreated":"1648613937","dateModified":"1648613937"}],"dateCreated":"1648613937","dateModified":"1648613938","status":"Needs Review"},{"id":"12368","callsign":"HG","title":"mercurial: use io.BytesIO instead of util.stringio","author":"indygreg","summary":"`util.stringio` is an alias to `io.BytesIO`. Let's just use `io.BytesIO`\ndirectly.\n\nI'm doing this because I noticed pytype was confused about types due to\nthe indirection.","testPlan":"","lineCount":"65","dependsOn":["12367"],"reviewers":["Alphare"],"ccs":["Alphare","mercurial-patches"],"actions":[{"type":"inline","comment":"This is unrelated and will probably break the current version of the CI (now that I think of it, I was supposed to figure out how to properly fix this annoyance last week and got sidetracked. I'll try to get to it this week.)","replyTo":null,"isNewFile":"1","line":"601","lineLength":"0","path":"mercurial\/patch.py","diffId":"32622","author":"Alphare","id":"189402","dateCreated":"1647253395","dateModified":"1647253395"},{"type":"reject","author":"Alphare","id":"189401","dateCreated":"1647253395","dateModified":"1647253395"},{"type":"update","diffId":"32622","author":"indygreg","id":"189330","dateCreated":"1646874473","dateModified":"1646874473"}],"dateCreated":"1646874473","dateModified":"1648200981","status":"Needs Revision"},{"id":"12370","callsign":"HG","title":"wireprotov2: delete remnants of wireprotov2","author":"indygreg","summary":"These were missed when wireprotov2 was deleted a few months ago.","testPlan":"","lineCount":"4052","dependsOn":["12369"],"reviewers":["Alphare"],"ccs":["Alphare","mercurial-patches"],"actions":[{"type":"comment","comment":"Thanks, it wasn't obvious that these were wireprotov2, but I'm sure you would know heh","author":"Alphare","id":"189398","dateCreated":"1647253169","dateModified":"1647253169"},{"type":"accept","author":"Alphare","id":"189397","dateCreated":"1647253169","dateModified":"1647253169"},{"type":"update","diffId":"32624","author":"indygreg","id":"189346","dateCreated":"1646874475","dateModified":"1646874475"}],"dateCreated":"1646874475","dateModified":"1647253169","status":"Accepted"},{"id":"12369","callsign":"HG","title":"run-tests: require Python 3.6","author":"indygreg","summary":"We recently dropped support for Python 3.5 in `setup.py`. Let's update\n`run-tests.py` to reflect the new reality.","testPlan":"","lineCount":"4","dependsOn":["12368"],"reviewers":["Alphare"],"ccs":["mercurial-patches"],"actions":[{"type":"accept","author":"Alphare","id":"189394","dateCreated":"1647253100","dateModified":"1647253100"},{"type":"update","diffId":"32623","author":"indygreg","id":"189338","dateCreated":"1646874474","dateModified":"1646874474"}],"dateCreated":"1646874474","dateModified":"1647253100","status":"Accepted"},{"id":"12367","callsign":"HG","title":"hgext: use io.BytesIO instead of util.stringio","author":"indygreg","summary":"util.stringio is an alias to io.BytesIO. Let's just use io.BytesIO\ndirectly.\n\nI'm doing this because I noticed that in some cases pytype wasn't able\nto infer the proper type of `util.stringio`. Removing the indirection\nwill enable type checking to work better.","testPlan":"","lineCount":"40","dependsOn":["12366"],"reviewers":["Alphare"],"ccs":["Kwan","mercurial-patches"],"actions":[{"type":"accept","author":"Alphare","id":"189392","dateCreated":"1647253084","dateModified":"1647253084"},{"type":"update","diffId":"32625","author":"indygreg","id":"189353","dateCreated":"1646874966","dateModified":"1646874966"},{"type":"update","diffId":"32621","author":"indygreg","id":"189322","dateCreated":"1646874472","dateModified":"1646874472"}],"dateCreated":"1646874472","dateModified":"1647253084","status":"Accepted"},{"id":"12366","callsign":"HG","title":"pycompat: add return type annotations","author":"indygreg","summary":"Now that we're using Python 3.6+, we can start using inline type\nannotations.\n\nI figured a good a place as any to start would be pycompat. So this\ncommit defines type annotations throughout the file.\n\nBecause we can't use deferred annotations parsing (since this feature\nrequires Python 3.7), complex types relying on symbols from the `typing`\nmodule use quoted expressions. This achieves some of the benefit of\ndeferred parsing without compromising the ability for type checkers to\ninfer things.\n\nWhen annotating `open()` as part of this change, pytype started\ncomplaining about a type mismatch in `profiling.py`. This turned out\nto be a false positive. So the error was suppressed.","testPlan":"","lineCount":"59","dependsOn":[],"reviewers":["Alphare"],"ccs":["Alphare","mercurial-patches"],"actions":[{"type":"inline","comment":"I think we should instead add an `assert` that `self._fp` is the right type, which would satisfy Pytype without disabling it and be more regression-proof.","replyTo":null,"isNewFile":"1","line":"275","lineLength":"0","path":"mercurial\/profiling.py","diffId":"32620","author":"Alphare","id":"189390","dateCreated":"1647252905","dateModified":"1647252905"},{"type":"reject","author":"Alphare","id":"189389","dateCreated":"1647252905","dateModified":"1647252905"},{"type":"update","diffId":"32620","author":"indygreg","id":"189314","dateCreated":"1646874472","dateModified":"1646874472"}],"dateCreated":"1646874472","dateModified":"1647252905","status":"Needs Revision"},{"id":"12360","callsign":"HG","title":"hglib: make sure configs can be passed to clone command","author":"Mathiasdm","summary":"","testPlan":"","lineCount":"6","dependsOn":[],"reviewers":[],"ccs":["mercurial-patches"],"actions":[{"type":"update","diffId":"32611","author":"Mathiasdm","id":"189256","dateCreated":"1646834902","dateModified":"1646834902"}],"dateCreated":"1646834902","dateModified":"1646834902","status":"Needs Review"},{"id":"12218","callsign":"HG","title":"black: blacken with 22.1.0","author":"indygreg","summary":"black 22.1.0 is the first non-beta release of black. I think it makes\nsense for us to adopt this version of black.\n\nThis commit blackens the repo with version 22.1.0.\n\nskip-blame: formatting only changes with black","testPlan":"","lineCount":"194","dependsOn":[],"reviewers":["Alphare"],"ccs":["Alphare","mercurial-patches"],"actions":[{"type":"comment","comment":">>! In D12218#187833, @indygreg wrote:\n>>>! In D12218#187693, @Alphare wrote:\n>> FYI I'm updating the heptapod CI to have this version of black as well. This might be a problem with `stable` since we'd need to use a different base CI image, but looking into pinning images was a long time coming anyway. I'll have a look at the rest of the patches in the meantime.\n> \n> Oh, was that in the repo? Did I miss it?\n\nIt's in a separate repo, I started the upgrade in response to this patch, so no worries.\n\n> Regarding stable, this series is small enough and it is early enough in the release cycle that we could probably apply this to stable with minimal effort. The sooner we do that the better, as there is bound to be churn on default soon.\n\nI think this is part of a deeper issue with how we manage our images and backwards-compat in the Heptapod CI.\n\nWe need a small amount of work to make sure that kind of upgrade goes well in the future (as we're bound to upgrade Rust, Black, etc. more). This series and the one that depends on it will have to wait until early next week when this work is done so we can properly and cleanly address the root cause.\n\nI'll still continue to review the patches so the potential back-and-forth needed can happen. I'm marking this as \"changes requested\" just as a flag for the issue above so as to not break the CI.","author":"Alphare","id":"188447","dateCreated":"1646303788","dateModified":"1646303788"},{"type":"reject","author":"Alphare","id":"188446","dateCreated":"1646303788","dateModified":"1646303788"},{"type":"update","diffId":"32406","author":"indygreg","id":"188146","dateCreated":"1646263261","dateModified":"1646263261"},{"type":"comment","comment":">>! In D12218#187693, @Alphare wrote:\n> FYI I'm updating the heptapod CI to have this version of black as well. This might be a problem with `stable` since we'd need to use a different base CI image, but looking into pinning images was a long time coming anyway. I'll have a look at the rest of the patches in the meantime.\n\nOh, was that in the repo? Did I miss it?\n\nRegarding stable, this series is small enough and it is early enough in the release cycle that we could probably apply this to stable with minimal effort. The sooner we do that the better, as there is bound to be churn on default soon.","author":"indygreg","id":"187833","dateCreated":"1646235733","dateModified":"1646235733"},{"type":"comment","comment":"FYI I'm updating the heptapod CI to have this version of black as well. This might be a problem with `stable` since we'd need to use a different base CI image, but looking into pinning images was a long time coming anyway. I'll have a look at the rest of the patches in the meantime.","author":"Alphare","id":"187693","dateCreated":"1646215898","dateModified":"1646215898"},{"type":"update","diffId":"32293","author":"indygreg","id":"187342","dateCreated":"1646180270","dateModified":"1646180270"}],"dateCreated":"1646180270","dateModified":"1646303879","status":"Needs Revision"},{"id":"12220","callsign":"HG","title":"tests: require black 22.1.0","author":"indygreg","summary":"We recently reformatted the repo with black 22.1.0. Since black 22.1.0\nis the first non-beta release of black and black is committed to\nkeeping the style stable for 1 year, I think it makes sense to bump\nthe required black verion to this version.","testPlan":"","lineCount":"4","dependsOn":["12219"],"reviewers":[],"ccs":["mercurial-patches"],"actions":[{"type":"update","diffId":"32295","author":"indygreg","id":"187356","dateCreated":"1646180275","dateModified":"1646180275"}],"dateCreated":"1646180275","dateModified":"1646180275","status":"Needs Review"},{"id":"12219","callsign":"HG","title":"automation: upgrade black to 22.1.0","author":"indygreg","summary":"We just reformatted the repo with black 22.1.0. Let's install this version\nof black in the Linux automation.","testPlan":"","lineCount":"120","dependsOn":["12218"],"reviewers":[],"ccs":["mercurial-patches"],"actions":[{"type":"update","diffId":"32294","author":"indygreg","id":"187348","dateCreated":"1646180273","dateModified":"1646180273"}],"dateCreated":"1646180273","dateModified":"1646180275","status":"Needs Review"},{"id":"11495","callsign":"HG","title":"narrow: make hg manifest only print things inside the narrowspec","author":"charlesetc","summary":"The performance of these commands seem roughly unchanged from the manual\ntesting I've done.","testPlan":"","lineCount":"18","dependsOn":[],"reviewers":["durin42","Alphare"],"ccs":["marmoute","martinvonz","spectral","Alphare","mercurial-patches"],"actions":[{"type":"comment","comment":">>! In D11495#176520, @Alphare wrote:\n>>>! In D11495#176365, @charlesetc wrote:\n>> The problem we've encountered is that people use hg manifest not as a debug command but as an equivalent to hg files - a way to list the files in a revision \/ repo. \n> \n> Seems to me that the `manifest` command is a \"lower-level\" command than `files`\n\nIt is mostly an older command. `files` is expected to replace `hg manifest`, but older user still use `hg manifest`\n","author":"marmoute","id":"187322","dateCreated":"1646069975","dateModified":"1646069975"},{"type":"comment","comment":">>! In D11495#176365, @charlesetc wrote:\n> The problem we've encountered is that people use hg manifest not as a debug command but as an equivalent to hg files - a way to list the files in a revision \/ repo. \n\nSeems to me that the `manifest` command is a \"lower-level\" command than `files` and really relates to the underlying datastructure, so it should probably not be affected by narrow (aside from potentially signaling in some way that some files are outside the narrow spec).","author":"Alphare","id":"176520","dateCreated":"1632906866","dateModified":"1632906866"},{"type":"comment","comment":"The problem we've encountered is that people use hg manifest not as a debug command but as an equivalent to hg files - a way to list the files in a revision \/ repo. ","author":"charlesetc","id":"176365","dateCreated":"1632839050","dateModified":"1632839050"},{"type":"comment","comment":">>! In D11495#176286, @martinvonz wrote:\n>>>! In D11495#176284, @durin42 wrote:\n>> I think that's a buggy test? @martinvonz and @spectral might have an opinion.\n> \n> I think I did it that way because I felt that `hg manifest` is a debug command so it might be useful to have the information about excluded trees there.\n\nThis comment highlights when it's useful to have `hg manifest` produce the more complete information: when using tree manifests :), otherwise `hg manifest` and `hg files` seem roughly equivalent to me (except that `hg manifest` can be coerced to print permissions\/flags\/hashes, and files can't. I think I'd slightly prefer if we could have a flag, possibly one that's only available when the narrow extension is loaded, that controls this behavior? I don't have any strong preferences for what the default is.\n\n> I never use it, however, so I don't mind if you change it.\n> \n> PS. I wonder if @charlesetc actually wanted to use `hg files`. If not, what's the reason for using `hg manifest`?\n\n","author":"spectral","id":"176287","dateCreated":"1632789963","dateModified":"1632789963"},{"type":"comment","comment":">>! In D11495#176284, @durin42 wrote:\n> I think that's a buggy test? @martinvonz and @spectral might have an opinion.\n\nI think I did it that way because I felt that `hg manifest` is a debug command so it might be useful to have the information about excluded trees there. I never use it, however, so I don't mind if you change it.\n\nPS. I wonder if @charlesetc actually wanted to use `hg files`. If not, what's the reason for using `hg manifest`?\n","author":"martinvonz","id":"176286","dateCreated":"1632780810","dateModified":"1632780810"},{"type":"comment","comment":"I think that's a buggy test? @martinvonz and @spectral might have an opinion.","author":"durin42","id":"176285","dateCreated":"1632765967","dateModified":"1632765967"},{"type":"comment","comment":"This breaks test output: https:\/\/foss.heptapod.net\/octobus\/mercurial-devel\/-\/jobs\/248654\n\nMaybe the manifest not being narrowed was on purpose for some reason? @durin42 could you shed some light?","author":"Alphare","id":"176281","dateCreated":"1632731369","dateModified":"1632731369"},{"type":"reject","author":"Alphare","id":"176280","dateCreated":"1632731369","dateModified":"1632731369"},{"type":"comment","comment":"Thanks! (also it's not just large repos, it's also those that just don't have `narrow`)","author":"Alphare","id":"176278","dateCreated":"1632729508","dateModified":"1632729508"},{"type":"accept","author":"Alphare","id":"176277","dateCreated":"1632729508","dateModified":"1632729508"},{"type":"comment","comment":"Thanks! How's that look?","author":"charlesetc","id":"176276","dateCreated":"1632506590","dateModified":"1632506590"},{"type":"update","diffId":"30403","author":"charlesetc","id":"176272","dateCreated":"1632506535","dateModified":"1632506535"},{"type":"comment","comment":"Nevermind, it seems that I dreamed that rule and it was never enforced, just convention.","author":"Alphare","id":"176254","dateCreated":"1632479388","dateModified":"1632479388"},{"type":"inline","comment":"I would add a check for `alwaysmatcher` to not run the filter if it's going to be useless anyway. I expect that large repositories could gain a little by doing this.","replyTo":null,"isNewFile":"1","line":"4776","lineLength":"0","path":"mercurial\/commands.py","diffId":"30391","author":"Alphare","id":"176246","dateCreated":"1632478798","dateModified":"1632478798"},{"type":"comment","comment":"The change looks good aside from my one comment. The commit description shouldn't be capitalized (after the topic part), I'm not sure why `test-check-commit.t` stopped picking that up.","author":"Alphare","id":"176245","dateCreated":"1632478798","dateModified":"1632478798"},{"type":"reject","author":"Alphare","id":"176244","dateCreated":"1632478798","dateModified":"1632478798"},{"type":"update","diffId":"30391","author":"charlesetc","id":"176204","dateCreated":"1632419472","dateModified":"1632419472"}],"dateCreated":"1632419472","dateModified":"1646069975","status":"Needs Revision"},{"id":"12207","callsign":"HG","title":"zstd: hack include order to ensure that our zstd.h is found","author":"joerg.sonnenberger","summary":"If the regular Python CFLAGS include directories that already have the\nzstd headers available, a different and possible incompatible version\ncan be picked up otherwise. Sadly, it seems like Python has no easy way\nto prefix flags before the rest.","testPlan":"","lineCount":"14","dependsOn":[],"reviewers":[],"ccs":["indygreg","mercurial-patches"],"actions":[{"type":"comment","comment":"Do you think we can do this upstream?\n\nI think the vendored version of python-zstandard can be upgraded to the latest version now that Python 2 support has been dropped. (Although there may be a Python 3.5 support question.)\n\nI'd prefer if we could facilitate this workaround in the upstream project and not require Mercurial to patch python-zstandard's sources.","author":"indygreg","id":"187263","dateCreated":"1645469481","dateModified":"1645469481"},{"type":"update","diffId":"32272","author":"joerg.sonnenberger","id":"187217","dateCreated":"1645451149","dateModified":"1645451149"}],"dateCreated":"1645451149","dateModified":"1645469481","status":"Needs Review"},{"id":"9677","callsign":"HG","title":"upgrade: use copy+delete instead of rename while creating backup","author":"pulkit","summary":"A lot of times, we do an upgrade operation which does not touches all the parts\nof the stores. But right not, we have a blind logic which processes everything.\nTo selectively upgrade parts of repository, we need to persist existing data\nwhich is untouched.\n\nHowever while creating current repository backup, we rename the whole store\nleaving no option to persist untouched files.\n\nWe switch to copy+delete so that we can only delete data files which are changed\nby the operation and leave rest untouched.","testPlan":"","lineCount":"40","dependsOn":[],"reviewers":["marmoute"],"ccs":["soap","udychris009","Djokovich","mharbison72","ulrickaka","marmoute","mercurial-patches"],"actions":[{"type":"comment","comment":"\nWatch Free Online Movies and TV Shows [[ https:\/\/soap2day.ink\/ | onsoap2day ]]","author":"soap","id":"187100","dateCreated":"1645044121","dateModified":"1645044121"},{"type":"comment","comment":"The Joint Admission and Matriculations Board (JAMB) has opened the portal for checking of admission status for the 2021\/2022 academic session. Also see <a href=\"https:\/\/www.currentschoolnews.com\/exam\/jamb-admission-status-checker\/\">check JAMB Admission Status<\/a>","author":"udychris009","id":"162613","dateCreated":"1620634964","dateModified":"1620634964"},{"type":"comment","comment":"I have been looking for this information for a long time, I was very surprised when I found it here. [[ https:\/\/routersetup.pro\/192-168-0-1 | 192.168.0.1 ]]\n","author":"Djokovich","id":"158954","dateCreated":"1618734028","dateModified":"1618734028"},{"type":"comment","comment":"Dropping this from stack for now to focus on getting other work pushed.","author":"pulkit","id":"149113","dateCreated":"1611240131","dateModified":"1611240131"},{"type":"plan-changes","author":"pulkit","id":"149112","dateCreated":"1611240131","dateModified":"1611240131"},{"type":"update","diffId":"24849","author":"pulkit","id":"147549","dateCreated":"1610628858","dateModified":"1610628858"},{"type":"comment","comment":"Note: that renaming a directory is instantaneous on any descent file system. copying full hierarchy is not.\n\nI am afraid your explanation is now confusing me. Can you try to explain what this patch is doing again ? ","author":"marmoute","id":"147388","dateCreated":"1610572678","dateModified":"1610572678"},{"type":"comment","comment":">>! In D9677#147172, @marmoute wrote:\n>>>! In D9677#147085, @mharbison72 wrote:\n>>>>! In D9677#146367, @pulkit wrote:\n>>>>>! In D9677#146243, @marmoute wrote:\n>>>> As pointed in a pa previous comment, this is problematic, because this does not preserve the same consistency as the previous code\n>>> \n>>> While the copy consistency can be maintained here, future changes (WIP) will break the consistency more. In upcoming work, we want to only touch parts of repository which needs to be updated. This will lead us to do selectively moving data from the upgraded repository to the current one.\n>> \n>> @marmoute are you OK with this explanation?\n> \n> Not at all :-)\n> \n> Currently we have:\n> 1) a fully consistent repository in place (while the upgrade run)\n> 2) a missing store during a split second (old store was rename)\n> 3) a fully consistent repository in place (the upgraded store was rename in place)\n> \n> The process ensure a very narrow inconsistency window and a very clear invalid state \"the store is either valid or missing.\"\n> \n> The change in this part move the (2) step to a much longer operation where elements get copied one by one. As a result we get a much longer window of inconsistency with a much wonkier inconsistency state as we get \"mixed\" files within the resulting store.\n\nNope, this patch does not do that. We have three stores here: backupstore (containing backup of current store), current store and upgraded store. Below is comparison of split second as part 2) mentioned above.\n\nBefore:\n\n1) Move current store to backup store\n2) Move upgraded store to current store\n\nStore inconsistency starts when step 1) starts and remains till step 2) finishes since both are move operation.\n\nAfter this patch:\n\n1) Copy current store to backup store\n2) Move upgraded store to current store\n\nIn this one, store inconsistency happens only at step 2) since step 1) is a copy.\n\nSo, this patch reduces the time when store was inconsistent.","author":"pulkit","id":"147240","dateCreated":"1610553408","dateModified":"1610553408"},{"type":"comment","comment":">>! In D9677#147085, @mharbison72 wrote:\n>>>! In D9677#146367, @pulkit wrote:\n>>>>! In D9677#146243, @marmoute wrote:\n>>> As pointed in a pa previous comment, this is problematic, because this does not preserve the same consistency as the previous code\n>> \n>> While the copy consistency can be maintained here, future changes (WIP) will break the consistency more. In upcoming work, we want to only touch parts of repository which needs to be updated. This will lead us to do selectively moving data from the upgraded repository to the current one.\n> \n> @marmoute are you OK with this explanation?\n\nNot at all :-)\n\nCurrently we have:\n1) a fully consistent repository in place (while the upgrade run)\n2) a missing store during a split second (old store was rename)\n3) a fully consistent repository in place (the upgraded store was rename in place)\n\nThe process ensure a very narrow inconsistency window and a very clear invalid state \"the store is either valid or missing.\"\n\nThe change in this part move the (2) step to a much longer operation where elements get copied one by one. As a result we get a much longer window of inconsistency with a much wonkier inconsistency state as we get \"mixed\" files within the resulting store.\n\nSo overall this change is going in the wrong direction.\n\nWe are currently looking for lighter upgrade for 2 feature \"persistent nodemap\" and \"share-safe\". And I don't think either of them need this kind of change. A upgrade processs for persistent nodemap could be:\n\n # write new persistent nodemaps (data file, then docket) that nobody will read without the requirements. \n # add the new requirement\n\nThe downgrade being the reverse (remove the requirement, remove the nodemaps)\n\nAnd something similar could be done for the share-safe upgrade\n\n # write a new `.hg\/store\/requirements` that nobody will read yet\n # rewrite `.hg\/requirements`","author":"marmoute","id":"147172","dateCreated":"1610534053","dateModified":"1610534053"},{"type":"reject","author":"marmoute","id":"147171","dateCreated":"1610534053","dateModified":"1610534053"},{"type":"update","diffId":"24774","author":"pulkit","id":"147170","dateCreated":"1610533896","dateModified":"1610533896"},{"type":"comment","comment":">>! In D9677#146367, @pulkit wrote:\n>>>! In D9677#146243, @marmoute wrote:\n>> As pointed in a pa previous comment, this is problematic, because this does not preserve the same consistency as the previous code\n> \n> While the copy consistency can be maintained here, future changes (WIP) will break the consistency more. In upcoming work, we want to only touch parts of repository which needs to be updated. This will lead us to do selectively moving data from the upgraded repository to the current one.\n\n@marmoute are you OK with this explanation?\n\nMy question is, would it be better to hardlink and then delete to avoid the copy overhead? (Of course not every filesystem supports that, but I think it falls back to a copy in that case.)","author":"mharbison72","id":"147085","dateCreated":"1610500850","dateModified":"1610500850"},{"type":"update","diffId":"24650","author":"pulkit","id":"146401","dateCreated":"1610131519","dateModified":"1610131519"},{"type":"comment","comment":">>! In D9677#146243, @marmoute wrote:\n> As pointed in a pa previous comment, this is problematic, because this does not preserve the same consistency as the previous code\n\nWhile the copy consistency can be maintained here, future changes (WIP) will break the consistency more. In upcoming work, we want to only touch parts of repository which needs to be updated. This will lead us to do selectively moving data from the upgraded repository to the current one.","author":"pulkit","id":"146367","dateCreated":"1610123806","dateModified":"1610123806"},{"type":"comment","comment":"As pointed in a pa previous comment, this is problematic, because this does not preserve the same consistency as the previous code","author":"marmoute","id":"146243","dateCreated":"1610074367","dateModified":"1610074367"},{"type":"reject","author":"marmoute","id":"146242","dateCreated":"1610074367","dateModified":"1610074367"},{"type":"comment","comment":"[[ http:\/\/www.essayempire.co.uk\/custom-essay-writing-service | Help With Essay ]]\nfrom the Academic Experts. Our essay writing service is designed to get you the extra help you need in completing your next university essay","author":"ulrickaka","id":"146070","dateCreated":"1609873493","dateModified":"1609873493"},{"type":"comment","comment":"I worried about having a much wider inconsistency window if we don't use rename. I'll have a deeper look later.","author":"marmoute","id":"145999","dateCreated":"1609837839","dateModified":"1609837839"},{"type":"update","diffId":"24564","author":"pulkit","id":"145922","dateCreated":"1609432989","dateModified":"1609432989"}],"dateCreated":"1609432989","dateModified":"1645044121","status":"Changes Planned"},{"id":"11563","callsign":"HG","title":"WIP working on making rust components compile on windows systems","author":"cspeckrun","summary":"","testPlan":"","lineCount":"470","dependsOn":[],"reviewers":["baymax"],"ccs":["pulkit","mharbison72","Alphare","SimonSapin","mercurial-patches"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"185842","dateCreated":"1643850363","dateModified":"1643850363"},{"type":"reject","author":"baymax","id":"185841","dateCreated":"1643850363","dateModified":"1643850363"},{"type":"comment","comment":"Note that with these changes compilation still doesn\u2019t succeed as the zstd crate runs into some linker errors (something about symbols already being defined). That\u2019s when using msvc, I tried to get gcc on my windows system but could not get it to function properly with rust.\n\nI was also planning to update the summary here to explain some of the changes, particularly with the crate dependency changes. ","author":"cspeckrun","id":"179019","dateCreated":"1634311926","dateModified":"1634311926"},{"type":"comment","comment":"@Alphare @SimonSapin @mharbison72 this might be of interest to you.","author":"pulkit","id":"178974","dateCreated":"1634303119","dateModified":"1634303119"},{"type":"comment","comment":"Fix typo in unix file permission","author":"cspeckrun","id":"177527","dateCreated":"1633232247","dateModified":"1633232247"},{"type":"update","diffId":"30590","author":"cspeckrun","id":"177526","dateCreated":"1633232247","dateModified":"1633232247"},{"type":"update","diffId":"30551","author":"cspeckrun","id":"177246","dateCreated":"1633148941","dateModified":"1633148941"}],"dateCreated":"1633148941","dateModified":"1643850363","status":"Needs Revision"},{"id":"11731","callsign":"HG","title":"rhg: lazily get filesystem metadata","author":"aalekseyev","summary":"rhg: use openat library for more efficient filesystem access","testPlan":"","lineCount":"281","dependsOn":[],"reviewers":["SimonSapin","baymax"],"ccs":["SimonSapin","mercurial-patches"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"185839","dateCreated":"1643850362","dateModified":"1643850362"},{"type":"reject","author":"baymax","id":"185838","dateCreated":"1643850362","dateModified":"1643850362"},{"type":"comment","comment":"@SimonSapin, this is a proof-of-concept patch I mentioned to you. It provides a large performance improvement in my benchmarks (in particular when running stat -mard), although I'm not entirely sure it's covered with tests.\nIt's not quite finished, in particular it doesn't handle the case when the filesystem doesn't return the file type. It also almost certainly doesn't work on Windows, but if we like the benchmarks then that can be worked out.","author":"aalekseyev","id":"180055","dateCreated":"1635855702","dateModified":"1635855702"},{"type":"update","diffId":"31011","author":"aalekseyev","id":"180049","dateCreated":"1635854771","dateModified":"1635854771"}],"dateCreated":"1635854771","dateModified":"1643850362","status":"Needs Revision"},{"id":"12001","callsign":"HG","title":"rust: upgrade to Clap 3","author":"martinvonz","summary":"Clap 3 was released about a week ago. Let's stay up to date.\n\nSome changes worth mentioning:\n\n * `AppSettings::VersionlessSubcommands` is on by default and deleted\n\n * `AllowInvalidUtf8` moved from `AppSettings` to `ArgSettings`. I set\n it only on the global args (`-R`, `--config`, `--cwd`). The other\n commands don't actually support invalid UTF-8, despite the setting\n being on at the top level. I'll leave it to someone else to switch\n to `value[s]_of_os()` and enable `AllowInvalidUtf8` on remaining\n arguments (where appropriate).\n\n * `Arg::short()` now takes a single character (used to take a\n string). That makes the leading dashes we have on strings passed to\n `Arg::long()` stand out (to me at least). I'll leave it to someone\n else to drop them if they care.","testPlan":"","lineCount":"212","dependsOn":[],"reviewers":["Alphare"],"ccs":["Alphare","mercurial-patches"],"actions":[{"type":"comment","comment":"Unfortunately we can't move forward with `clap` version 3 since it requires a version of Rust that is too recent for our policy. https:\/\/github.com\/clap-rs\/clap\/blob\/master\/CHANGELOG.md#minimum-required-rust\n\nI was looking into the only change that seems like it might cause an issue (the invalid utf8 stuff), and this patch just wouldn't compile under 1.48.0. We're going to have to wait until Debian Bookworm releases.","author":"Alphare","id":"183902","dateCreated":"1642413874","dateModified":"1642413874"},{"type":"reject","author":"Alphare","id":"183901","dateCreated":"1642413874","dateModified":"1642413874"},{"type":"update","diffId":"31657","author":"martinvonz","id":"183869","dateCreated":"1642198896","dateModified":"1642198896"}],"dateCreated":"1642198896","dateModified":"1642413874","status":"Needs Revision"},{"id":"11307","callsign":"HG","title":"run-tests: avoid silently switching the hg executable used","author":"mharbison72","summary":"I noticed an issue testing the installed pyoxidizer binary using `--with-hg`\nwhere it would pass more tests than if the tests are run with `--pyoxidized`.\nIt turns out that `_usecorrectpython()` augments `PATH` to include the python\nbinary and its `Scripts` directory on Windows, and I happen to have `pip`\ninstalled Mercurial in that version of python. Therefore, the `which()` method\npicked up this installed executable, and wrote that to the generated `hg` script\nin the custom `bin` directory.\n\nThere's an issue here when running `test-run-tests.t` with `--local`, as noted\nin the comments. I suspect that some stuff from the main instance of\n`run-tests.py` is bleeding into the *.t file's instances of `run-tests.py`\nbecause when I print `opts.with_hg` at the point where is complains that\n\"--with-hg must specify an executable hg script\", the path is in the form\n\"C:\\\\\\\\Users\\\\\\\\Matt\\\\\\\\...\". (Two of those slashes are escapes the test runner\nputs into printed lines.) If I hardcode r\"C:\\Users\\Matt\\...\" in `run-tests.py`,\nthen it works fine.","testPlan":"","lineCount":"15","dependsOn":[],"reviewers":["abhishekaggarwal9520817742"],"ccs":["Alphare","marmoute","mercurial-patches"],"actions":[{"type":"comment","comment":"I need my real identity","author":"abhishekaggarwal9520817742","id":"183378","dateCreated":"1640459965","dateModified":"1640459965"},{"type":"reject","author":"abhishekaggarwal9520817742","id":"183377","dateCreated":"1640459965","dateModified":"1640459965"},{"type":"accept","author":"abhishekaggarwal9520817742","id":"183376","dateCreated":"1640458191","dateModified":"1640458191"},{"type":"inline","comment":"\/s\/used\/use\/","replyTo":null,"isNewFile":"1","line":"3682","lineLength":"0","path":"tests\/run-tests.py","diffId":"29935","author":"Alphare","id":"173914","dateCreated":"1629884763","dateModified":"1629884763"},{"type":"comment","comment":">>! In D11307#173446, @mharbison72 wrote:\n> I don\u2019t have a way to test that with the rust and chg variants.\n\nYou mean under Windows or in general? Because this also feels wrong to me, we should probably be keeping the full path around.","author":"Alphare","id":"173913","dateCreated":"1629884763","dateModified":"1629884763"},{"type":"comment","comment":">>! In D11307#173445, @marmoute wrote:\n> I seems a bit weird to be that we try to manually put `self._bindir` and `self._hgcommand` together while if I am not mistaken, they both originate from the splitting of some absolute path somewhere. So keeping that absolute path around would seems safer\/cleaner to me. However I might be missing something.\n\nYeah, that\u2019s where it comes from and I agree it would be better. I\u2019m trying to avoid adding a new variable holding the full path, because I don\u2019t have a way to test that with the rust and chg variants.","author":"mharbison72","id":"173446","dateCreated":"1629329372","dateModified":"1629329372"},{"type":"comment","comment":"I seems a bit weird to be that we try to manually put `self._bindir` and `self._hgcommand` together while if I am not mistaken, they both originate from the splitting of some absolute path somewhere. So keeping that absolute path around would seems safer\/cleaner to me. However I might be missing something.","author":"marmoute","id":"173445","dateCreated":"1629324810","dateModified":"1629324810"},{"type":"comment","comment":"Not sure that we want to take this as-is (even though it does avoid a bad problem outside of the internal tests). I'm hoping someone has some insight and saves me some time trial and erroring through this.","author":"mharbison72","id":"173443","dateCreated":"1629320920","dateModified":"1629320920"},{"type":"update","diffId":"29935","author":"mharbison72","id":"173438","dateCreated":"1629320400","dateModified":"1629320400"}],"dateCreated":"1629320400","dateModified":"1640459965","status":"Needs Revision"},{"id":"11680","callsign":"HG","title":"push: add option to abort on dirty working copy if parent is pushed","author":"martinvonz","summary":"This patch adds a config option to make it an error to push the parent\nof the working copy when the working copy is dirty. We have had this\nfeature enabled by default internally for a few years. I think most\nusers have found it helpful.","testPlan":"","lineCount":"123","dependsOn":[],"reviewers":["Alphare"],"ccs":["Alphare","spectral","marmoute","pulkit","mercurial-patches"],"actions":[{"type":"comment","comment":">>! In D11680#182205, @spectral wrote:\n>> \n>> ### Should Flag negation be rare ?\n>> \n>> I disagree here. We should use clearest available verb for flags, using negation to get the meaning we need. I would draw a similarity with boolean naming in the code, where we don't have a preferred \"default\" state for the common case, but we phrase the boolean in a way that is easy to read.\n>> \n>> In addition, having a mix of negation and non-negation as common case will help make the (negation) feature more discoverable.\n>> \n>> What's your rationale for wanting them to be rare ?\n> \n> The biggest reason is because there's currently, as far as I know, no support in Mercurial's flag parser code for tribools, so these won't be annotated with the `[no-]` prefix in the help text.\n\nI see, \"None\" and \"True\" value get treated the same in that regard. It seems a small technical limitation that is fairly easy to lift. Do you have other reasons to be against them ?\n\n> \n>> \n>> ### Should the proposed behavior be part of tweakdefault ?\n>> \n>> I don't think so, `hg push` is reasonably independent from the working copy and it is a common use-case to push with uncommitted changes (pushing the working copy parent or not). Making it disabled by default seems weird to me.\n> \n> I can't describe how many times the internal version of this check we have at Google has saved me from making a mistake. I would recommend that you check whether you truly do want to do this frequently or not :)\n\nI am curious if the warning version of this would give you most of the benefit with none of the anoyance. Did you gave it a try ? (see my previous comment about \"forgetting to add a files\" as a bonus)","author":"marmoute","id":"182991","dateCreated":"1639681673","dateModified":"1639748407"},{"type":"comment","comment":"> \n> ### Should Flag negation be rare ?\n> \n> I disagree here. We should use clearest available verb for flags, using negation to get the meaning we need. I would draw a similarity with boolean naming in the code, where we don't have a preferred \"default\" state for the common case, but we phrase the boolean in a way that is easy to read.\n> \n> In addition, having a mix of negation and non-negation as common case will help make the (negation) feature more discoverable.\n> \n> What's your rationale for wanting them to be rare ?\n\nThe biggest reason is because there's currently, as far as I know, no support in Mercurial's flag parser code for tribools, so these won't be annotated with the `[no-]` prefix in the help text.\n\n> \n> ### Should the proposed behavior be part of tweakdefault ?\n> \n> I don't think so, `hg push` is reasonably independent from the working copy and it is a common use-case to push with uncommitted changes (pushing the working copy parent or not). Making it disabled by default seems weird to me.\n\nI can't describe how many times the internal version of this check we have at Google has saved me from making a mistake. I would recommend that you check whether you truly do want to do this frequently or not :) \n\n> \n> A related behavior\/config is `commands.commit.post-status` that display information about dirty content after the commit (including about unknown files !). I feel like it could catch most\u00b9 of the error case you are trying to catch here (or at least, it would in my case). With a much smoother impact on the common workflow.\n\nI did not know about that and I just turned it on, because that sounds really nice. But this would not actually cover what we're trying to do, as it requires the user to remember to run commit or whatever, and that's what we're trying to check that they did :P\n\n> \n> [1] even more since it would catch the \"forgot to add a file\" case.\n> \n> ### Should we have a \"warning\" version of this behavior ?\n> \n> In my opinion : Yes, it brings most of the value with very few drawbacks.\n> \n> ### Should we use `--allow-dirty-wc` or `--no-check-dirty-wc`.\n> \n> I prefer the `--check` wording :\n> \n> * it is more consistent with `hg update --check`,\n> * the `--no-check` version is clearer that a validation step have been explicitly dropped\n\nI guess this comes down to whether we expect this in tweakdefaults or not; regardless of whether it's actually going to be in tweakdefaults, we're going to enable it at Google for everyone. When combined with my preference for not having flag negations, we end up with the --allow wording, and that's what we currently have it named internally. I really think it *should* be added to tweakdefaults, but I'll admit that my own personal usage of Mercurial might not match what non-Google users of Mercurial do, and maybe this causes issues with some workflows there. \n\nLike I said before, I also think it's going to be exceedingly rare, if this isn't part of tweakdefaults, for someone to *enable* on the commandline. No one is going to start typing `hg push --check`, they'll either forget to specify it, or they'll turn on the option somehow. So in my mind the flag is purely an \"escape hatch\" for \"no, I really want to do this\", and the word \"allow\" conveys that quite well.","author":"spectral","id":"182205","dateCreated":"1638908899","dateModified":"1638908899"},{"type":"inline","comment":"See my above comment about doing this later in the exchange when we have the final set of revisions.","replyTo":null,"isNewFile":"1","line":"5753","lineLength":"0","path":"mercurial\/commands.py","diffId":"30973","author":"Alphare","id":"181810","dateCreated":"1638544877","dateModified":"1638544877"},{"type":"inline","comment":"This assumption seems false to me? For example, you can push only some drafts (if the remote already has some of them) and your parent(s) might be a secret? \n\nI think this revset would make more sense: `(parents() and ancestors(%ln)) and not secret()`. You're asking the question \"am I pushing my parents\", regardless of phase... excluding secrets.\n\nAlso, this is done really high up and happens before the discovery, which means that you're not really working with the actual set of revisions you're pushing. This could probably cause subtle bugs with some extensions? Might as well not take the risk and do it inside `exchange.push`.","replyTo":null,"isNewFile":"1","line":"1118","lineLength":"0","path":"mercurial\/cmdutil.py","diffId":"30973","author":"Alphare","id":"181809","dateCreated":"1638544877","dateModified":"1638544877"},{"type":"reject","author":"Alphare","id":"181808","dateCreated":"1638544877","dateModified":"1638544877"},{"type":"comment","comment":">>! In D11680#180023, @spectral wrote:\n>>>! In D11680#179988, @marmoute wrote:\n>> The ability to use `--no-` variants is fairly new (a couple of year maybe ?), but I (and others) have been trying to put it to good use since then. Since is quite new I don't think they so many of of such flag yet, but a notable example of that approach is `--merge` that I use daily.\n> \n> As in `hg update --no-merge`? I don't see how that does anything, I might be missing something?\n> \n> ```\n> @command(\n> b'update|up|checkout|co',\n> [... (b'm', b'merge', None, _(b'merge uncommitted changes')), ...]\n> )\n> def update(ui, repo, node=None, **opts):\n> ...\n> merge = opts.get('merge')\n> ...\n> if check:\n> updatecheck = b'abort'\n> elif merge: # Truthiness check only\n> updatecheck = b'none'\n> ```\n> \n> The only way that might do something is if you have something in [defaults] that sets --merge to true, such that this overrides it.\n\nYou are right, I expected this to work but this wasn't implemented, the `--merge` properly override the config, but `--no-merge` did not override the other way around.\n\nSo I fixed it in D11851, and it now does.\n\n>> I agree that in this case one of the variants seems less useful as the other, but it does not seem useless either. For example it has obvious usage in script and alias. Having it can also help to build a more consistent experience around boolean flag. (and who knows what users would actually use)\n>> \n>> Regarding `check` vs `allow`, I find `no-check` better than `no-allow` (that I feel a bit awkward). Regarding consistency with existing options, `hg update` has as notable `--check` flag, that check for a dirty working directory.\n> \n> I'm trying us to the most desirable end state, which I hope is that this gets added to tweakdefaults, at which point we'd have the following scenarios:\n> - tweakdefaults enabled: user runs `hg push` and it fails, telling the user to run `hg push --allow-dirty`; they do so. If they hit this frequently, they either disable this config knob or learn to type `hg push --allow`\n> - tweakdefaults not enabled [current state]: user runs `hg push` and it succeeds, uploads even though they have a dirty working directory. Never learns about the config option.\n> - script (which should be using HGPLAIN=1 to disable tweakdefaults): `hg push` behaves like before, `hg push --no-allow-dirty` works if they actually want that behavior. \n> - aliases: I imagine it'll be rare that people make an alias like `safepush = push --no-allow-dirty`, but this is still something that the user does very infrequently, while I expect the interactive typing to be more common\n> \n> In this set of cases, the first one is the one I think we should be optimizing for. The other three are cases where writing it like `--check-dirty` makes sense, but I would argue that it doesn't matter that there's more cases, because the number of times it happens (for scripts and aliases) is much lower, and the interactive user in the second case would be much better served by enabling tweakdefaults (or at least this config option).\n> \n> In my opinion, flag negations should be rare. We also have the problem that if we're actually creating a tri-state boolean, we currently do not have any mechanism in the flag parsing code to show those properly in the help text. This will show up as:\n> \n> ```\n> --allow-dirty allow pushing with a dirty working copy, overriding\n> commands.push.check-dirty=abort (EXPERIMENTAL)\n> ```\n> \n> with no `[no-]` prefix, because it's not recognized as a tribool.\n\nI can see multiple questions here with an agreement level varying from one question to another. So let me try to split them apart for clarity.\n\n### Should there be a config for this behavior ?\n\nIn my opinion : Yes,\n(and I think we have a consensus)\n\n### Should this be a tri-state option ? (True\/None\/False; that override the config value when \u2260 None)\n\nIn my opinion : Yes, that seems more logical and make good use of `--no-prefix`\n\n(I am unclear about what the consensus currently is)\n\n### Should Flag negation be rare ?\n\nI disagree here. We should use clearest available verb for flags, using negation to get the meaning we need. I would draw a similarity with boolean naming in the code, where we don't have a preferred \"default\" state for the common case, but we phrase the boolean in a way that is easy to read.\n\nIn addition, having a mix of negation and non-negation as common case will help make the (negation) feature more discoverable.\n\nWhat's your rationale for wanting them to be rare ?\n\n### Should the proposed behavior be part of tweakdefault ?\n\nI don't think so, `hg push` is reasonably independent from the working copy and it is a common use-case to push with uncommitted changes (pushing the working copy parent or not). Making it disabled by default seems weird to me.\n\nA related behavior\/config is `commands.commit.post-status` that display information about dirty content after the commit (including about unknown files !). I feel like it could catch most\u00b9 of the error case you are trying to catch here (or at least, it would in my case). With a much smoother impact on the common workflow.\n\n[1] even more since it would catch the \"forgot to add a file\" case.\n\n### Should we have a \"warning\" version of this behavior ?\n\nIn my opinion : Yes, it brings most of the value with very few drawbacks.\n\n### Should we use `--allow-dirty-wc` or `--no-check-dirty-wc`.\n\nI prefer the `--check` wording :\n\n* it is more consistent with `hg update --check`,\n* the `--no-check` version is clearer that a validation step have been explicitly dropped\n\n\n","author":"marmoute","id":"181805","dateCreated":"1638543620","dateModified":"1638543620"},{"type":"comment","comment":">>! In D11680#179988, @marmoute wrote:\n> The ability to use `--no-` variants is fairly new (a couple of year maybe ?), but I (and others) have been trying to put it to good use since then. Since is quite new I don't think they so many of of such flag yet, but a notable example of that approach is `--merge` that I use daily.\n\nAs in `hg update --no-merge`? I don't see how that does anything, I might be missing something?\n\n```\n@command(\n b'update|up|checkout|co',\n [... (b'm', b'merge', None, _(b'merge uncommitted changes')), ...]\n)\ndef update(ui, repo, node=None, **opts):\n ...\n merge = opts.get('merge')\n ...\n if check:\n updatecheck = b'abort'\n elif merge: # Truthiness check only\n updatecheck = b'none'\n```\n\nThe only way that might do something is if you have something in [defaults] that sets --merge to true, such that this overrides it.\n\n> \n> I agree that in this case one of the variants seems less useful as the other, but it does not seem useless either. For example it has obvious usage in script and alias. Having it can also help to build a more consistent experience around boolean flag. (and who knows what users would actually use)\n> \n> Regarding `check` vs `allow`, I find `no-check` better than `no-allow` (that I feel a bit awkward). Regarding consistency with existing options, `hg update` has as notable `--check` flag, that check for a dirty working directory.\n\nI'm trying us to the most desirable end state, which I hope is that this gets added to tweakdefaults, at which point we'd have the following scenarios:\n- tweakdefaults enabled: user runs `hg push` and it fails, telling the user to run `hg push --allow-dirty`; they do so. If they hit this frequently, they either disable this config knob or learn to type `hg push --allow`\n- tweakdefaults not enabled [current state]: user runs `hg push` and it succeeds, uploads even though they have a dirty working directory. Never learns about the config option.\n- script (which should be using HGPLAIN=1 to disable tweakdefaults): `hg push` behaves like before, `hg push --no-allow-dirty` works if they actually want that behavior. \n- aliases: I imagine it'll be rare that people make an alias like `safepush = push --no-allow-dirty`, but this is still something that the user does very infrequently, while I expect the interactive typing to be more common\n\nIn this set of cases, the first one is the one I think we should be optimizing for. The other three are cases where writing it like `--check-dirty` makes sense, but I would argue that it doesn't matter that there's more cases, because the number of times it happens (for scripts and aliases) is much lower, and the interactive user in the second case would be much better served by enabling tweakdefaults (or at least this config option).\n\nIn my opinion, flag negations should be rare. We also have the problem that if we're actually creating a tri-state boolean, we currently do not have any mechanism in the flag parsing code to show those properly in the help text. This will show up as:\n\n```\n --allow-dirty allow pushing with a dirty working copy, overriding\n commands.push.check-dirty=abort (EXPERIMENTAL)\n```\n\nwith no `[no-]` prefix, because it's not recognized as a tribool.","author":"spectral","id":"180023","dateCreated":"1635536564","dateModified":"1635536564"},{"type":"comment","comment":"The ability to use `--no-` variants is fairly new (a couple of year maybe ?), but I (and others) have been trying to put it to good use since then. Since is quite new I don't think they so many of of such flag yet, but a notable example of that approach is `--merge` that I use daily.\n\nI agree that in this case one of the variants seems less useful as the other, but it does not seem useless either. For example it has obvious usage in script and alias. Having it can also help to build a more consistent experience around boolean flag. (and who knows what users would actually use)\n\nRegarding `check` vs `allow`, I find `no-check` better than `no-allow` (that I feel a bit awkward). Regarding consistency with existing options, `hg update` has as notable `--check` flag, that check for a dirty working directory.","author":"marmoute","id":"179988","dateCreated":"1635496495","dateModified":"1635496495"},{"type":"inline","comment":"Kyle and I looked for existing examples of tri-state flags. The only one we could find was `hg purge`'s `--comfirm` argument: If neither `--confirm` nor `-no-confirm` is passed, then the default value depends on whether the `purge` extension is loaded. I can make `hg push` behave similarly (defaulting to the config value if neither `--allow-dirty` nor `--no-allow-dirty` is passed). Is that what we want? I don't care which (except that I've already implemented it as a regular, non-tri-state flag).","replyTo":"179888","isNewFile":"1","line":"5638","lineLength":"0","path":"mercurial\/commands.py","diffId":"30843","author":"martinvonz","id":"179899","dateCreated":"1635287673","dateModified":"1635287673"},{"type":"inline","comment":"> I am not sure what is your question here ? We allowing --no- variant for boolean flags has been around for a while and is used in various places.\n\nIf the default value of the flag is `False`, then passing `--no-check-dirty` is the same as not passing it. Do you mean that the default should be `None` (i.e. a tri-state)?\n\nWhat other flag(s) were you thinking of that use `--check-*` rather than `--allow-*`?","replyTo":"179814","isNewFile":"1","line":"5638","lineLength":"0","path":"mercurial\/commands.py","diffId":"30843","author":"martinvonz","id":"179897","dateCreated":"1635287403","dateModified":"1635287403"},{"type":"comment","comment":"Kyle message made me realize that I had not sent mine, so I'm doing that now.","author":"martinvonz","id":"179896","dateCreated":"1635287403","dateModified":"1635287403"},{"type":"inline","comment":"I believe there's two requests - a tri-state bool, and a renaming of the flag. I like the idea of the tri-state bool, but dislike the suggested name; I don't think that `--check-dirty` would be used often (if you remember to specify it manually, you can just run `hg status` -- it'd only be useful in scripts), and we might consider adding this behavior to tweakdefaults in the future; requiring --no- flags to override \"default\" safety features feels backwards.","replyTo":"179814","isNewFile":"1","line":"5638","lineLength":"0","path":"mercurial\/commands.py","diffId":"30843","author":"spectral","id":"179888","dateCreated":"1635268321","dateModified":"1635268321"},{"type":"inline","comment":"> > To match other UI better we could have a --check-dirty flag that would turn the feature on and an --no-check-dirty who disable it.\n\n> Do you mean a tri-state flag? Where do we currently use that?\n\nI am not sure what is your question here ? We allowing --no- variant for boolean flags has been around for a while and is used in various places. Including with a config option that control the default value. (e.g. `hg update --merge`)","replyTo":"179812","isNewFile":"1","line":"5638","lineLength":"0","path":"mercurial\/commands.py","diffId":"30843","author":"marmoute","id":"179814","dateCreated":"1634837256","dateModified":"1634837256"},{"type":"inline","comment":"> To match other uI better we could have a `--check-dirty` flag that would turn the feature on and an `--no-check-dirty` who disable it.\n\nDo you mean a tri-state flag? Where do we currently use that?\n\n> With a `commands.push.check-dirty` (or something similar) that control the default value\/behavior of this flag.\n\nGood point. We already have `commands.update.check`, which is already used by commands other than `update`, so even if we decide to use this new `commands.push.check-dirty` from other commands, it won't be any worse.","replyTo":"179056","isNewFile":"1","line":"5638","lineLength":"0","path":"mercurial\/commands.py","diffId":"30843","author":"martinvonz","id":"179812","dateCreated":"1634836765","dateModified":"1634836765"},{"type":"inline","comment":"Makes sense.","replyTo":"179045","isNewFile":"1","line":"1874","lineLength":"0","path":"mercurial\/configitems.py","diffId":"30843","author":"martinvonz","id":"179811","dateCreated":"1634836765","dateModified":"1634836765"},{"type":"comment","comment":"> With a commands.push.check-dirty (or something similar) that control the default value\/behavior of this flag.\n\n","author":"martinvonz","id":"179810","dateCreated":"1634836765","dateModified":"1634836765"},{"type":"update","diffId":"30973","author":"martinvonz","id":"179808","dateCreated":"1634836760","dateModified":"1634836760"},{"type":"inline","comment":"To match other uI better we could have a `--check-dirty` flag that would turn the feature on and an `--no-check-dirty` who disable it.\n\nWith a `commands.push.check-dirty` (or something similar) that control the default value\/behavior of this flag.\n\nWhat do you think?","replyTo":null,"isNewFile":"1","line":"5638","lineLength":"0","path":"mercurial\/commands.py","diffId":"30843","author":"marmoute","id":"179056","dateCreated":"1634489127","dateModified":"1634489127"},{"type":"inline","comment":"nit: IIRC, in other configs, we use `allow`, `warn` and `abort` as options. Push on dirty working copy set to ignore seems a bit confusing to me.","replyTo":null,"isNewFile":"1","line":"1874","lineLength":"0","path":"mercurial\/configitems.py","diffId":"30843","author":"pulkit","id":"179045","dateCreated":"1634409657","dateModified":"1634409657"},{"type":"comment","comment":"I am big +1 on this and will personally use it. Thanks!","author":"pulkit","id":"179044","dateCreated":"1634409657","dateModified":"1634409657"},{"type":"update","diffId":"30843","author":"martinvonz","id":"179030","dateCreated":"1634341945","dateModified":"1634341945"}],"dateCreated":"1634341945","dateModified":"1639681673","status":"Needs Revision"},{"id":"11252","callsign":"HG","title":"debugupgraderepo: add fix-metaencoding-flag pass for issue6528","author":"joerg.sonnenberger","summary":"","testPlan":"","lineCount":"49","dependsOn":[],"reviewers":["Alphare"],"ccs":["Alphare","marmoute","mercurial-patches"],"actions":[{"type":"reject","author":"Alphare","id":"179199","dateCreated":"1634558745","dateModified":"1634558745"},{"type":"comment","comment":"@joerg.sonnenberger The rewrite utils have been committed in 5.9, this can be rebased and refactored to reuse the same logic.","author":"Alphare","id":"173830","dateCreated":"1629821105","dateModified":"1629821105"},{"type":"comment","comment":"This is similar to D11239, having this done during upgrade too seems useful, but having a simpler\/more-focussed command for this seems important (and \"on-fly-fix\" during exchange too.\n\nIdeally we would take D11239 first and reuse its bulding block for that diff afterward.","author":"marmoute","id":"172677","dateCreated":"1628101328","dateModified":"1628101328"},{"type":"update","diffId":"29789","author":"joerg.sonnenberger","id":"172660","dateCreated":"1628084238","dateModified":"1628084238"}],"dateCreated":"1628084238","dateModified":"1634558745","status":"Needs Revision"},{"id":"11453","callsign":"HG","title":"log: if there is a merge state, show conflictother for . [WIP]","author":"joerg.sonnenberger","summary":"","testPlan":"","lineCount":"42","dependsOn":[],"reviewers":["martinvonz"],"ccs":["martinvonz","Alphare","mercurial-patches"],"actions":[{"type":"inline","comment":"Hmm, I feel like the label should instead be a boolean (or two) indicating whether the commit is in the `conflictother()` or `conflictlocal()` revsets. This might then look like this:\n\n```\n @ changeset: 5:f1d5f53e397b\n | tag: tip\n | parent: 3:e28fd7fa7938\n | merging: other\n | user: shelve@localhost\n | date: Thu Jan 01 00:00:00 1970 +0000\n | summary: changes to: add A to bars\n |\n | @ changeset: 4:fe451a778c81\n |\/ merging: local\n | user: test\n | date: Thu Jan 01 00:00:00 1970 +0000\n | summary: add C to bars\n```\n\nThat may be a good way of helping the user understand what \"local\" and \"other\" in the conflict markers mean.","replyTo":null,"isNewFile":"1","line":"1420","lineLength":"12","path":"tests\/test-shelve.t","diffId":"30296","author":"martinvonz","id":"175907","dateCreated":"1632243055","dateModified":"1632243055"},{"type":"reject","author":"martinvonz","id":"175906","dateCreated":"1632243055","dateModified":"1632243055"},{"type":"comment","comment":"That looks like a good quality of life improvement!","author":"Alphare","id":"175607","dateCreated":"1632128327","dateModified":"1632128327"},{"type":"update","diffId":"30296","author":"joerg.sonnenberger","id":"175562","dateCreated":"1631965673","dateModified":"1631965673"}],"dateCreated":"1631965673","dateModified":"1632243055","status":"Needs Revision"},{"id":"7177","callsign":"HG","title":"rebase: introduce optional parent mapping","author":"joerg.sonnenberger","summary":"Consider the following DAG:\n\n C C'\n |\\ \/|\n A B D\n\nwith the goal of rebasing C to C' while switching the A parent to D.\nOut of the box, rebase will fail here as it doesn't know which parent of\nC to rewrite. With the new --parentmap option, this can be specified\nexplicitly. Use cases for this functionality are dealing with manual\nrebases without obsolescence markers, e.g. git-style forced commits.","testPlan":"","lineCount":"94","dependsOn":[],"reviewers":["martinvonz","baymax"],"ccs":["mercurial-patches","marmoute","mercurial-devel"],"actions":[{"type":"comment","comment":">>! In D7177#175507, @joerg.sonnenberger wrote:\n> From the VC call today: The use case can be addressed by marking parents as to-be-preserved, so that for merge commits rebase can decide on the parent link is should operate on. It covers a general DAG and is somewhat easier to use in terms of UX than the parentmap, but can provide the same functionality with a multi-step rebase.\n\nYeah, something like `--preserve-parent XXX` where XXX is a set a revs to \"preserve\". When rebasing a revision, if it has parents in XXX we keep them (and rebase the other). if no parent are in XXX, we don't care.","author":"marmoute","id":"175508","dateCreated":"1631887375","dateModified":"1631887375"},{"type":"comment","comment":"From the VC call today: The use case can be addressed by marking parents as to-be-preserved, so that for merge commits rebase can decide on the parent link is should operate on. It covers a general DAG and is somewhat easier to use in terms of UX than the parentmap, but can provide the same functionality with a multi-step rebase.","author":"joerg.sonnenberger","id":"175507","dateCreated":"1631887139","dateModified":"1631887139"},{"type":"inline","comment":"`REV:REV` is valid revset so the result is quite confusing, if we go that route, we need anothr syntax.","replyTo":null,"isNewFile":"1","line":"884","lineLength":"0","path":"hgext\/rebase.py","diffId":"17411","author":"marmoute","id":"128831","dateCreated":"1591780504","dateModified":"1591780504"},{"type":"comment","comment":">>! In D7177#128760, @martinvonz wrote:\n>>>! In D7177#128757, @marmoute wrote:\n>>>>! In D7177#128756, @martinvonz wrote:\n>>>>>! In D7177#128740, @marmoute wrote:\n>>>>>>! In D7177#128389, @martinvonz wrote:\n>>>>> Maybe another option is to allow multiple `-d` arguments for this case? Something like `hg rebase -r C -d B -d D`. I haven't thought through BC, but I think that's what I'd prefer if we were writing rebase from scratch. I know we can't support `hg rebase -r C -d 'B + D'` for backward-compatibility reasons (because we already support that -- it rebases to the highest revnum in the set).\n>>>> \n>>>> That's interresting. How would that works with a practical case ?\n>>> \n>>> The example I have was meant to be a practical example for how to do it in the case given in the patch description :) But let me know if you meant some other aspect of \"how it works\". As I said, I'm not sure ant the BC bit of it at least.\n>> \n>> I meant how that would work in general, esepcially case more complicated than the basic base shown by @joerg.sonnenberger.\n> \n> I think the parents chosen by `-d` should only apply to the roots of the rebase set. If your rebase set has multiple roots and only some of them are merge commits, then we should probably error out.\n\nSo you suggestion would be to allow to specify two -d that would definive the two new parents of the root ? I suspect it would be a bit too narrow compared to the varienty of case we might have to handle. Maybe this is a mission for PlanPlan.\n\n> Anyway, I'm not sure it's realistic to make it work that way now, especially because of how inconsistent it would be with other arguments that accept revsets and only care about the highest revnum in the set (I think that was a mistake to do, but I understand why it was done that way and it's obviously too late to change it).\n\nI think the multiple -d value approach would works fine. (but for the other issue).\n\n>> Not that in @joerg base, B being ancestors of both C and C', we could probably behave better by default directly. Could we not ?\n> \n> As @joerg said in the patch description, there's no reasonable way to choose which of A and B to preserve (the current version of rebase wouldn't preserve either and would instead rebase all of A, B, and C).\n\nThe description got me confused, (I though C was rebased on C' (finding the naming strange)) while this is about C being rebased on D.\n\n","author":"marmoute","id":"128830","dateCreated":"1591780504","dateModified":"1591780504"},{"type":"comment","comment":">>! In D7177#128757, @marmoute wrote:\n>>>! In D7177#128756, @martinvonz wrote:\n>>>>! In D7177#128740, @marmoute wrote:\n>>>>>! In D7177#128389, @martinvonz wrote:\n>>>> Maybe another option is to allow multiple `-d` arguments for this case? Something like `hg rebase -r C -d B -d D`. I haven't thought through BC, but I think that's what I'd prefer if we were writing rebase from scratch. I know we can't support `hg rebase -r C -d 'B + D'` for backward-compatibility reasons (because we already support that -- it rebases to the highest revnum in the set).\n>>> \n>>> That's interresting. How would that works with a practical case ?\n>> \n>> The example I have was meant to be a practical example for how to do it in the case given in the patch description :) But let me know if you meant some other aspect of \"how it works\". As I said, I'm not sure ant the BC bit of it at least.\n> \n> I meant how that would work in general, esepcially case more complicated than the basic base shown by @joerg.sonnenberger.\n\nI think the parents chosen by `-d` should only apply to the roots of the rebase set. If your rebase set has multiple roots and only some of them are merge commits, then we should probably error out.\n\nAnyway, I'm not sure it's realistic to make it work that way now, especially because of how inconsistent it would be with other arguments that accept revsets and only care about the highest revnum in the set (I think that was a mistake to do, but I understand why it was done that way and it's obviously too late to change it).\n\n> \n> Not that in @joerg base, B being ancestors of both C and C', we could probably behave better by default directly. Could we not ?\n\nAs @joerg said in the patch description, there's no reasonable way to choose which of A and B to preserve (the current version of rebase wouldn't preserve either and would instead rebase all of A, B, and C).","author":"martinvonz","id":"128760","dateCreated":"1591719313","dateModified":"1591719313"},{"type":"comment","comment":">>! In D7177#128756, @martinvonz wrote:\n>>>! In D7177#128740, @marmoute wrote:\n>>>>! In D7177#128389, @martinvonz wrote:\n>>> Maybe another option is to allow multiple `-d` arguments for this case? Something like `hg rebase -r C -d B -d D`. I haven't thought through BC, but I think that's what I'd prefer if we were writing rebase from scratch. I know we can't support `hg rebase -r C -d 'B + D'` for backward-compatibility reasons (because we already support that -- it rebases to the highest revnum in the set).\n>> \n>> That's interresting. How would that works with a practical case ?\n> \n> The example I have was meant to be a practical example for how to do it in the case given in the patch description :) But let me know if you meant some other aspect of \"how it works\". As I said, I'm not sure ant the BC bit of it at least.\n\nI meant how that would work in general, esepcially case more complicated than the basic base shown by @joerg.sonnenberger.\n\nNot that in @joerg base, B being ancestors of both C and C', we could probably behave better by default directly. Could we not ?","author":"marmoute","id":"128757","dateCreated":"1591717623","dateModified":"1591717623"},{"type":"comment","comment":">>! In D7177#128740, @marmoute wrote:\n>>>! In D7177#128389, @martinvonz wrote:\n>> Maybe another option is to allow multiple `-d` arguments for this case? Something like `hg rebase -r C -d B -d D`. I haven't thought through BC, but I think that's what I'd prefer if we were writing rebase from scratch. I know we can't support `hg rebase -r C -d 'B + D'` for backward-compatibility reasons (because we already support that -- it rebases to the highest revnum in the set).\n> \n> That's interresting. How would that works with a practical case ?\n\nThe example I have was meant to be a practical example for how to do it in the case given in the patch description :) But let me know if you meant some other aspect of \"how it works\". As I said, I'm not sure ant the BC bit of it at least.","author":"martinvonz","id":"128756","dateCreated":"1591712758","dateModified":"1591712758"},{"type":"comment","comment":">>! In D7177#128389, @martinvonz wrote:\n> Maybe another option is to allow multiple `-d` arguments for this case? Something like `hg rebase -r C -d B -d D`. I haven't thought through BC, but I think that's what I'd prefer if we were writing rebase from scratch. I know we can't support `hg rebase -r C -d 'B + D'` for backward-compatibility reasons (because we already support that -- it rebases to the highest revnum in the set).\n\nThat's interresting. How would that works with a practical case ?","author":"marmoute","id":"128740","dateCreated":"1591703040","dateModified":"1591703040"},{"type":"comment","comment":"Maybe another option is to allow multiple `-d` arguments for this case? Something like `hg rebase -r C -d B -d D`. I haven't thought through BC, but I think that's what I'd prefer if we were writing rebase from scratch. I know we can't support `hg rebase -r C -d 'B + D'` for backward-compatibility reasons (because we already support that -- it rebases to the highest revnum in the set).","author":"martinvonz","id":"128389","dateCreated":"1590862104","dateModified":"1590862104"},{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"126385","dateCreated":"1587570775","dateModified":"1587570775"},{"type":"reject","author":"baymax","id":"126384","dateCreated":"1587570775","dateModified":"1587570775"},{"type":"comment","comment":"I like the idea of using adding this to graft.","author":"marmoute","id":"117272","dateCreated":"1579797555","dateModified":"1579797555"},{"type":"comment","comment":"I personally haven't queued this yet because I don't really like the UI. Some things I recently worked on made me realize that `hg graft` doesn't currently preserve merges, but we could probably easily add a `--preserve-merges` option to it, so `hg co D; hg graft --base B --preserve-merges` would take care of the case in the commit message.","author":"martinvonz","id":"116330","dateCreated":"1579212527","dateModified":"1579212527"},{"type":"comment","comment":"I changed the commit message to indent the graph by two spaces. That way it renders better here in Phabricator.","author":"martinvonz","id":"105323","dateCreated":"1572413915","dateModified":"1572413915"},{"type":"update","diffId":"17411","author":"joerg.sonnenberger","id":"105313","dateCreated":"1572292928","dateModified":"1572292928"},{"type":"update","diffId":"17410","author":"joerg.sonnenberger","id":"105307","dateCreated":"1572279428","dateModified":"1572279428"}],"dateCreated":"1572279427","dateModified":"1631887375","status":"Needs Revision"},{"id":"10271","callsign":"HG","title":"tests: replace a use of rebaseskipobsolete=0 by `hg rebase --keep`","author":"martinvonz","summary":"I'm about to delete the `experimental.rebaseskipobsolete` config, so\nthis test case won't be able to exist in its current form. This patch\nupdates it to use `--keep` instead of `--config\nexperimental.rebaseskipobsolete=off` to allow it to rebase pruned\ncommits. I suspect some of the cases covered by the test will no\nlonger be tested now, but that doesn't matter if we make those cases\nimpossible by removing the config (some later patch).","testPlan":"","lineCount":"13","dependsOn":[],"reviewers":["baymax"],"ccs":["mercurial-patches"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"173363","dateCreated":"1629293982","dateModified":"1629293982"},{"type":"reject","author":"baymax","id":"173362","dateCreated":"1629293982","dateModified":"1629293982"},{"type":"update","diffId":"26599","author":"martinvonz","id":"156362","dateCreated":"1616715357","dateModified":"1616715357"}],"dateCreated":"1616715357","dateModified":"1629293982","status":"Needs Revision"},{"id":"9056","callsign":"HG","title":"fix: include adjacent blank lines in ranges to be fixed","author":"msuozzo","summary":"When you remove a statement in python and the two adjacent lines are blank,\nthis can create lint errors due to improper spacing. I'm sure this is also the\ncase with other whitespace-aware languages and file formats. The current fix\ncommand skips all removal diffs and so doesn't trigger the auto-formatting of\nthat whitespace.\n\nNet Cost:\n- Two extra line checks for all diffs and fix ranges that could be 1-2 lines\n longer.\n- One extra fix range generated for each pure-removal diff.\nNet Benefit:\n- Whitespace-aware languages are able to format and resolve whitespace errors.","testPlan":"","lineCount":"205","dependsOn":[],"reviewers":["hooper","baymax"],"ccs":["pulkit","mercurial-patches"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"173360","dateCreated":"1629293981","dateModified":"1629293981"},{"type":"reject","author":"baymax","id":"173359","dateCreated":"1629293981","dateModified":"1629293981"},{"type":"comment","comment":">>! In D9056#149670, @msuozzo wrote:\n> What's the next step here? Is there still disagreement on the value of the feature or does there need to be additional review(s)?\n\nSorry lost track of the discussion. While the code change looks good, like @hooper I am not sure whether it's a good idea to do so.\n\nOthers: what do you think about this?","author":"pulkit","id":"157676","dateCreated":"1618184085","dateModified":"1618184085"},{"type":"comment","comment":"What's the next step here? Is there still disagreement on the value of the feature or does there need to be additional review(s)?","author":"msuozzo","id":"149670","dateCreated":"1611700517","dateModified":"1611700517"},{"type":"comment","comment":">>! In D9056#147377, @hooper wrote:\n> The patch looks fine now.\n\nGreat!\n\n> \n> I still think we shouldn't go down the road of implementing formatting behavior abstractly on top of the actual formatters. Ideally, we would pass flags to the formatter that ask it to do the right language-aware thing at the byte\/line offset of a deletion. It's going to be awkward to support\/document this if\/when we get a solution like that.\n\nI agree in principle \/\/but\/\/ I think the lack of support for those features in actual formatters indicates that this config option will still provide meaningful value to users. If\/when popular formatters support this sort of adjacency detection, it may make sense to sunset this sort of feature but I'm not confident that will happen soon.","author":"msuozzo","id":"147389","dateCreated":"1610572876","dateModified":"1610572876"},{"type":"comment","comment":"The patch looks fine now.\n\nI still think we shouldn't go down the road of implementing formatting behavior abstractly on top of the actual formatters. Ideally, we would pass flags to the formatter that ask it to do the right language-aware thing at the byte\/line offset of a deletion. It's going to be awkward to support\/document this if\/when we get a solution like that.","author":"hooper","id":"147377","dateCreated":"1610569221","dateModified":"1610569221"},{"type":"comment","comment":"Bump","author":"msuozzo","id":"146708","dateCreated":"1610383620","dateModified":"1610383620"},{"type":"comment","comment":"Expanded the doctests a bit and factored out some of the index arithmetic.","author":"msuozzo","id":"145934","dateCreated":"1609568116","dateModified":"1609568116"},{"type":"update","diffId":"24566","author":"msuozzo","id":"145931","dateCreated":"1609568042","dateModified":"1609568042"},{"type":"update","diffId":"24565","author":"msuozzo","id":"145930","dateCreated":"1609567743","dateModified":"1609567743"},{"type":"inline","comment":"This is where you can add simple tests for the overlapping line ranges issue.\n\nYou might want to expand these test cases anyway, so we can be more confident we're not changing the behavior when the new config is off.","replyTo":null,"isNewFile":"1","line":"615","lineLength":"0","path":"hgext\/fix.py","diffId":"23292","author":"hooper","id":"138918","dateCreated":"1603492665","dateModified":"1603492665"},{"type":"inline","comment":"Sorry, I just realized this gets passed through unionranges() later on (to combine line ranges computed from multiple \"diff base\" commits). Not sure if we really need to ensure that this function returns non-overlapping ranges, but it seems like it might prevent mistakes later. The code is not strictly necessary here, though.","replyTo":null,"isNewFile":"1","line":"647","lineLength":"0","path":"hgext\/fix.py","diffId":"23292","author":"hooper","id":"138917","dateCreated":"1603492665","dateModified":"1603492665"},{"type":"inline","comment":"Reworded a bit. PTAL","replyTo":"138771","isNewFile":"1","line":"625","lineLength":"0","path":"hgext\/fix.py","diffId":"23265","author":"msuozzo","id":"138884","dateCreated":"1603402036","dateModified":"1603402036"},{"type":"comment","comment":"Okay the implementation itself looks better to me.\n\nAs for the multi-formatter considerations, I just don't think it should play a big role in whether this feature is worthwhile. This clearly addresses a configurability knob that didn't previously exist and I think that alone should dictate the viability of this patch.","author":"msuozzo","id":"138883","dateCreated":"1603402036","dateModified":"1603402036"},{"type":"update","diffId":"23292","author":"msuozzo","id":"138881","dateCreated":"1603401708","dateModified":"1603401708"},{"type":"inline","comment":"I still suggest combining adjacent\/overlapping ranges.","replyTo":null,"isNewFile":"1","line":"640","lineLength":"0","path":"hgext\/fix.py","diffId":"23265","author":"hooper","id":"138774","dateCreated":"1603328030","dateModified":"1603328030"},{"type":"inline","comment":"I would prefer \":\" instead of \": \", or at least \" : \".","replyTo":null,"isNewFile":"1","line":"638","lineLength":"0","path":"hgext\/fix.py","diffId":"23265","author":"hooper","id":"138773","dateCreated":"1603328030","dateModified":"1603328030"},{"type":"inline","comment":"Might be more readable to give this expression a name:\n\ndeletion = (firstline == lastline)","replyTo":null,"isNewFile":"1","line":"626","lineLength":"0","path":"hgext\/fix.py","diffId":"23265","author":"hooper","id":"138772","dateCreated":"1603328030","dateModified":"1603328030"},{"type":"inline","comment":"\"Produce a line range for every addition and modification. Conditionally produce ranges for deletions.\"","replyTo":null,"isNewFile":"1","line":"625","lineLength":"0","path":"hgext\/fix.py","diffId":"23265","author":"hooper","id":"138771","dateCreated":"1603328030","dateModified":"1603328030"},{"type":"inline","comment":"The O(lines) initialization of blanks2 is still happening whether or not we use it.","replyTo":"138242","isNewFile":"1","line":"607","lineLength":"0","path":"hgext\/fix.py","diffId":"22764","author":"hooper","id":"138770","dateCreated":"1603328030","dateModified":"1603328030"},{"type":"comment","comment":"The config changes are a big improvement, but I'm still not sure if it's worth supporting. One thing to note is that this feature doesn't help users who have multiple formatters behind a wrapper script configured as a single fixer tool. Configuring it as multiple fixer tools is possible, but not always practical, since it may duplicate some logic between the hg config and something else (sorry to be vague about that).","author":"hooper","id":"138769","dateCreated":"1603328030","dateModified":"1603328030"},{"type":"inline","comment":"this is probably obsolete given the change but I did try to more rigorously define what I'm considering \"whitespace\" here.","replyTo":"138241","isNewFile":"1","line":"49","lineLength":"0","path":"hgext\/fix.py","diffId":"22939","author":"msuozzo","id":"138695","dateCreated":"1603160466","dateModified":"1603160466"},{"type":"comment","comment":"I'm definitely sympathetic to your position.\n\nAs discussed offline, I think an improvement to generality would be to change this config option to relate to deletion diff policies instead and have adjacent blanks be a policy therein.\n\nI'm flexible on naming here. I think \"emitdeletedranges\" is a bit clunky but I can't think of something that fits much better.\n\nPTAL and thanks!","author":"msuozzo","id":"138694","dateCreated":"1603160466","dateModified":"1603160466"},{"type":"update","diffId":"23265","author":"msuozzo","id":"138691","dateCreated":"1603159658","dateModified":"1603159658"},{"type":"inline","comment":"This change introduces the possibility that the appended line range is adjacent to the previous one. I think we should extend the existing line range instead of adding another one. This will avoid exposing that corner case in formatter tools, which will make this extension more reliable in practice. It may also be a performance improvement for some tools that don't consider this case.\n\nPlease include another test case for that, regardless.","replyTo":null,"isNewFile":"1","line":"622","lineLength":"0","path":"hgext\/fix.py","diffId":"22939","author":"hooper","id":"138243","dateCreated":"1602622767","dateModified":"1602622767"},{"type":"inline","comment":"We can additionally make the extra work conditional on the config value.","replyTo":"136885","isNewFile":"1","line":"607","lineLength":"0","path":"hgext\/fix.py","diffId":"22764","author":"hooper","id":"138242","dateCreated":"1602622767","dateModified":"1602622767"},{"type":"inline","comment":"I would explain this more fully by framing it, roughly, as three points:\n1. There is a config that will expand *all* changed line ranges to include adjacent blank lines.\n2. This is useful because it inhibits the previously described omission of deleted line ranges, allowing code formatters to fix whitespace surrounding deletions.\n3. The subtleties of how we define \"adjacent\" and \"blank line\".","replyTo":null,"isNewFile":"1","line":"49","lineLength":"0","path":"hgext\/fix.py","diffId":"22939","author":"hooper","id":"138241","dateCreated":"1602622767","dateModified":"1602622767"},{"type":"comment","comment":"Consider this C++ example:\n\n```\n#include <foo>\n\n#include \"foo.h\"\n```\n\nDeleting the blank line would ideally lead clang-format to add the blank line back. Implementing this kind of behavior on the basis of adjacent blank lines will never provide a complete solution.\n\nNow consider this example:\n\n```\nvoid foo() {\n int y;\n if (true) { \n int x;\n } \n}\n```\n\nDelete `int y;`, then format the two adjacent lines unconditionally. The indentation of `int x;` will be fixed, even though it has nothing to do with the diff. This behavior counteracts the purpose of the feature in an avoidable way.\n\nI don't think there is any middle ground here, unless it involves language-aware analysis of the diff. I don't think that belongs here. A more robust solution is to communicate deletions in a precise way to the tools. For example, I think clang-format can reasonably accept it as a zero-length range at a byte offset. How to best express this in configuration is an open question, but it would maintain the separation of concerns between version control and language tools.\n\nI think this change is reducing the robustness of the established interface. It provides some utility, but it also over-promises on its ability to handle deletions. It might be more appropriate as a separate extension that wraps the `difflineranges` function.","author":"hooper","id":"138240","dateCreated":"1602622767","dateModified":"1602622767"},{"type":"comment","comment":"@hooper can you please have a look again. Thank you!","author":"pulkit","id":"137503","dateCreated":"1601973454","dateModified":"1601973454"},{"type":"inline","comment":"Yeah I really considered this but ended up sticking with the current implementation since it meant a byte-wise comparison which I thought would be much faster than a slice comparison.\n\nHowever if we're doing the blank-line calculation once at the top of the function, making it whitespace instead is trivial. Done.","replyTo":"136359","isNewFile":"1","line":"620","lineLength":"0","path":"hgext\/fix.py","diffId":"22764","author":"msuozzo","id":"136886","dateCreated":"1601419555","dateModified":"1601419555"},{"type":"inline","comment":"I'd done this because this is passed to mdiff so I'd assumed that mdiff was already paying the price for storing this construct.\n\nAgain, I'd assumed this was more efficient than the alternative but if you're concerned about the cost, I can definitely calculate whitespace-only lines instead.","replyTo":"136357","isNewFile":"1","line":"607","lineLength":"0","path":"hgext\/fix.py","diffId":"22764","author":"msuozzo","id":"136885","dateCreated":"1601419555","dateModified":"1601419555"},{"type":"update","diffId":"22939","author":"msuozzo","id":"136882","dateCreated":"1601419428","dateModified":"1601419428"},{"type":"inline","comment":"Are we really looking for blank lines, or whitespace-only lines? Does it need to be configurable? I'm worried this behavior is overly specific to your use case.","replyTo":null,"isNewFile":"1","line":"620","lineLength":"0","path":"hgext\/fix.py","diffId":"22764","author":"hooper","id":"136359","dateCreated":"1601075379","dateModified":"1601075379"},{"type":"inline","comment":"You might be able to get away with \"printf\" here, and a newline in :linerange. Not sure about portability, but I've been told to use printf instead of echo before.","replyTo":null,"isNewFile":"1","line":"1486","lineLength":"0","path":"tests\/test-fix.t","diffId":"22764","author":"hooper","id":"136358","dateCreated":"1601075379","dateModified":"1601075379"},{"type":"inline","comment":"I don't think anyone has put a lot of effort into profiling this code, but I'm worried this might increase peak memory use by a significant factor. With large files, this can put users at increased risk of memory exhaustion, swapping, etc. Architectural changes to prevent that are out of scope for this change.\n\nComputing a set of indices for blank lines might be more efficient.","replyTo":null,"isNewFile":"1","line":"607","lineLength":"0","path":"hgext\/fix.py","diffId":"22764","author":"hooper","id":"136357","dateCreated":"1601075379","dateModified":"1601075379"},{"type":"comment","comment":"Alright so as discussed, this is now a per-fixer config option which I called \"adjacentblanks\" (not married to it). There's also the new issue of having to plumb the flag down through the necessary layers of abstraction. I figured doing so with a fixer instance would be the least complex way but I'm not sure how idiomatic that is in hg's codebase.","author":"msuozzo","id":"135964","dateCreated":"1600833067","dateModified":"1600833067"},{"type":"update","diffId":"22764","author":"msuozzo","id":"135963","dateCreated":"1600832888","dateModified":"1600832888"},{"type":"comment","comment":"> Your \":deletion\" suggestion is related to the possibility of supporting \"zero-length byte offset ranges\" or \"zero-length line ranges\" in addition to \"line ranges.\" In general, I would recommend avoiding the temptation to complicate the interface between fix.py and formatter tools. Most of the formatters I've had to integrate with did not support \"formatting a deletion\" anyway. There are some important counter examples like clang-format.\n\nTurns out that was my own comment about :deletion. I see this change as a workaround for formatters that don't explicitly support formatting around deleted sections, regardless of whether we ever implement a way to integrate with formatters that do support it.\n\nI oppose enabling this as default behavior. A plausible way this could go wrong is if formatting an unchanged blank line also implicitly formats an unchanged block of code on the other side. I don't think we can assume that tools will never do this. I do think it would be surprising in a bad way for users, even if we technically don't make any guarantees about the minimal-ness of the diffs used to determine incremental formatting. Not formatting deletions also sucks, but it's less destructive.","author":"hooper","id":"135906","dateCreated":"1600816365","dateModified":"1600816365"},{"type":"comment","comment":"I'm not sure how general the \"blank lines\" heuristic actually is. I think this should be an opt-in feature based on a per-formatter config variable. You can start with an entry in \"FIXER_ATTRS\" and a check around line 685. Whatever we end up with, it needs to be documented in the module docstring (which is the source for hg help -e fix)\n\nI don't have a list of examples handy, but I wouldn't be surprised if this produces bad results in relatively common cases. This tends to be subjective, but we don't want to ship a foot gun :)\n\nYour \":deletion\" suggestion is related to the possibility of supporting \"zero-length byte offset ranges\" or \"zero-length line ranges\" in addition to \"line ranges.\" In general, I would recommend avoiding the temptation to complicate the interface between fix.py and formatter tools. Most of the formatters I've had to integrate with did not support \"formatting a deletion\" anyway. There are some important counter examples like clang-format.","author":"hooper","id":"135887","dateCreated":"1600793545","dateModified":"1600793545"},{"type":"update","diffId":"22738","author":"msuozzo","id":"135740","dateCreated":"1600457474","dateModified":"1600457474"}],"dateCreated":"1600457474","dateModified":"1629293981","status":"Needs Revision"},{"id":"9135","callsign":"HG","title":"doc: Generate separate commands\/topics\/extension web pages.","author":"ludovicchabant","summary":"","testPlan":"","lineCount":"507","dependsOn":[],"reviewers":["baymax"],"ccs":["marmoute","durin42","mercurial-patches"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"173357","dateCreated":"1629293980","dateModified":"1629293980"},{"type":"reject","author":"baymax","id":"173356","dateCreated":"1629293980","dateModified":"1629293980"},{"type":"comment","comment":"@ludovicchabant gentle re-ping","author":"marmoute","id":"159284","dateCreated":"1618912200","dateModified":"1618912200"},{"type":"comment","comment":"@ludovicchabant gentle ping","author":"marmoute","id":"146369","dateCreated":"1610124822","dateModified":"1610124822"},{"type":"comment","comment":"I'm fine with this as long as it still works on Python 3. Can you confirm this works under Python 3? Maybe rebase it to `@` for completeness, since it's been a while.\n\nSorry for slow responses.","author":"durin42","id":"145929","dateCreated":"1609556764","dateModified":"1609556764"},{"type":"comment","comment":"Derp... phabricator didn't send me any email notification....\n\nAnyway, if the implementation is roughly ok we can do a code review and queue it for next release. If not, I can redo it using a better approach? I'm not sure what \"RFC\" and \"landing\" mean in the specific context of the mercurial release workflow, so whichever one is more appropriate is fine by me! The main things I'd like to have feedback on are:\n\n1) The method I'm using here requires a recent Make (for instance, the one that ships by default on macOS won't work). I don't know if there's a better way to do this?\n2) This generates a bunch of intermediate and final files, which increases the `make docs` time. I don't know if process time is an issue here, or if it's OK because it's run only once per release?\n3) I took a bit of creative freedom for the format of the new pages. This is easy to iterate upon a bit later but it's worth taking a look at the output in case you have any opinions.\n\nThanks!","author":"ludovicchabant","id":"142904","dateCreated":"1606949877","dateModified":"1606950187"},{"type":"comment","comment":"I like it. Did you intend this as an RFC, or for landing?","author":"durin42","id":"138354","dateCreated":"1602704486","dateModified":"1602704486"},{"type":"comment","comment":"Hi there... this patch is a proof of concept, and probably entirely the wrong approach since I was learning Makefiles almost from scratch as I was doing it (and then by the end realized it only works with recent versions of Make). But I'd like to put the basic idea of the change up for review at least before I continue working on it.\n\nThe basic idea is that the [[ https:\/\/www.mercurial-scm.org\/doc\/hg.1.html | Mercurial reference page ]] is too damn big and unwieldy. Its size also makes it hard to search for something only for a given command. One could search through the help output in a terminal but there is tremendous value in having a well organized and friendly website. Anyway, this change makes it possible to spit out separate web pages for each command, topic, and extension, along with a classified index page that links to all of them.\n\nThanks","author":"ludovicchabant","id":"137028","dateCreated":"1601502000","dateModified":"1601502037"},{"type":"update","diffId":"22957","author":"ludovicchabant","id":"137022","dateCreated":"1601501721","dateModified":"1601501721"}],"dateCreated":"1601501721","dateModified":"1629293980","status":"Needs Revision"},{"id":"10272","callsign":"HG","title":"rebase: drop support for rebaseskipobsolete config","author":"martinvonz","summary":"`hg rebase` has been able to skip obsolete commits since 92409f8dff5d\n(rebase: don't rebase obsolete commit whose successor is already\nrebased, 2015-09-14). That commit introduced the\n`experimental.rebaseskipobsolete` config and set it to false by\ndefault to start with. Then it has been enabled by default since\na47881680402 (rebase: turn rebaseskipobsolete on by default,\n2016-03-09).\n\nIt seems to me that all use cases for turning off the config are\ncovered by `hg rebase --keep`, `hg graft`, or `hg touch`. The use\ncases I can think of are:\n\n 1) Create a temporary copy of a set of commits for some\n experimentation (use `hg rebase --keep` or `hg graft`).\n\n 2) Revive a pruned commit (use `hg touch`, possibly followed by `hg\n rebase` if you want to move it elsewhere).\n\nAlso, it is a config option after all, which means that it is not\nintended for one-off `hg rebase` commands (then it would have been a\ncommand-line flag). So, let's drop support for this config since it\nseems unused. It will make my work on making `rewriteutil.precheck()`\ncheck for divergence slightly simpler.","testPlan":"","lineCount":"24","dependsOn":["10271"],"reviewers":["marmoute"],"ccs":["pulkit","marmoute","mercurial-patches"],"actions":[{"type":"comment","comment":">>! In D10272#157102, @marmoute wrote:\n>>>! In D10272#157092, @pulkit wrote:\n>> I am +1 on this. I remember there was a discussion on IRC around it but not sure what the end result of that was. @marmoute does having `experimental.rebaseskipobsolete` serves any purpose?\n> \n> Ha yes, thanks for the ping. The short version of my opinion is that experience has shown over and over that having a way to says \"select exactly what I requested without tempering with it\" are useful. Therefore, we should not drop the flag currently allowing to do that without at least introducing another one.\n> \n> Neither `hg rebase` is quite powerfull tool and neither `rebase --keep`, `hg graft` or `hg touch` (?) can really do the same thing. So they don't seem like proper alternative to a simple \"do-what-I-said\" config\/flag.\n\nProbably we need a `--exact` or something similar which also does not skip commits which are already in destination and create empty commits for them too.","author":"pulkit","id":"171826","dateCreated":"1626812604","dateModified":"1626812604"},{"type":"comment","comment":">>! In D10272#157092, @pulkit wrote:\n> I am +1 on this. I remember there was a discussion on IRC around it but not sure what the end result of that was. @marmoute does having `experimental.rebaseskipobsolete` serves any purpose?\n\nHa yes, thanks for the ping. The short version of my opinion is that experience has shown over and over that having a way to says \"select exactly what I requested without tempering with it\" are useful. Therefore, we should not drop the flag currently allowing to do that without at least introducing another one.\n\nNeither `hg rebase` is quite powerfull tool and neither `rebase --keep`, `hg graft` or `hg touch` (?) can really do the same thing. So they don't seem like proper alternative to a simple \"do-what-I-said\" config\/flag.","author":"marmoute","id":"157102","dateCreated":"1617902158","dateModified":"1617902158"},{"type":"reject","author":"marmoute","id":"157101","dateCreated":"1617902158","dateModified":"1617902158"},{"type":"comment","comment":"I am +1 on this. I remember there was a discussion on IRC around it but not sure what the end result of that was. @marmoute does having `experimental.rebaseskipobsolete` serves any purpose?","author":"pulkit","id":"157093","dateCreated":"1617901277","dateModified":"1617901277"},{"type":"update","diffId":"26600","author":"martinvonz","id":"156370","dateCreated":"1616715358","dateModified":"1616715358"}],"dateCreated":"1616715358","dateModified":"1626812604","status":"Needs Revision"},{"id":"9636","callsign":"HG","title":"bundle: add option to avoid checking further delta candidates [POC]","author":"joerg.sonnenberger","summary":"Especially when applying a clone bundle and the follow-up pull, the\ndeltas will be nearly optimal. Add a test config flag to skip any\nattempts at finding a better delta base. Test base for how this\ninteracts with parallel delta compression in addgroup.\n\nTest with a bundle of the HG repo: -2%, non-noticable size difference\nTest with a bundle of the NetBSD src repo: -18%, +10% manifest size","testPlan":"","lineCount":"30","dependsOn":[],"reviewers":["indygreg","baymax"],"ccs":["marmoute","mercurial-patches"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"164487","dateCreated":"1621935151","dateModified":"1621935151"},{"type":"reject","author":"baymax","id":"164486","dateCreated":"1621935151","dateModified":"1621935151"},{"type":"comment","comment":">>! In D9636#145536, @joerg.sonnenberger wrote:\n> It was primarily meant to identify problem areas. The primary win here is skipping the delta finding for manifests. It seems like the problem is that we force a delta to be generated for snapshots and the target repo doesn't completely agree on when snapshots are supposed to happen. Given the size of the manifests here, the delta generation is reasonable expensive.\n\nDo you have timing about the amount of time we spend in snapshot\/semi-snapshot vs the rest of the unbundle ?","author":"marmoute","id":"145577","dateCreated":"1608627272","dateModified":"1608627272"},{"type":"comment","comment":"It was primarily meant to identify problem areas. The primary win here is skipping the delta finding for manifests. It seems like the problem is that we force a delta to be generated for snapshots and the target repo doesn't completely agree on when snapshots are supposed to happen. Given the size of the manifests here, the delta generation is reasonable expensive.","author":"joerg.sonnenberger","id":"145536","dateCreated":"1608599736","dateModified":"1608599736"},{"type":"comment","comment":"I feel like effrot would be better spend generating better bundle (or adding more delta related information in the bundle) than doing this kind of changes.","author":"marmoute","id":"145319","dateCreated":"1608421082","dateModified":"1608421082"},{"type":"comment","comment":"Some further tests show that this is indeed primarily the manifest handling. There are some peculiarities with the commit graph of this specific repository, so this likely doesn't apply to other repositories as much.","author":"joerg.sonnenberger","id":"145317","dateCreated":"1608418432","dateModified":"1608418432"},{"type":"update","diffId":"24442","author":"joerg.sonnenberger","id":"145300","dateCreated":"1608389045","dateModified":"1608389045"}],"dateCreated":"1608389045","dateModified":"1621935151","status":"Needs Revision"},{"id":"9274","callsign":"HG","title":"internals: start to document how .hg\/ works","author":"indygreg","summary":"This commit adds internals documentation that starts to document the\nfiles and semantics of the .hg\/ directory.\n\nA lot of this functionality is currently only documented via code\n(that doesn't count as documentation!). And the semantics are often wonky\nenough that it warrants documentation.\n\nI set out attempting to document the file layout for .hg\/. Along the\nway, I realized I also needed to document the semantics of lock files,\nthe path encoding of the revlog store, and how transactions work.\n\nThe documentation is missing critical information, such as a thorough\naccounting of all the random files in .hg\/ and .hg\/store and their\nformats. But perfect is the enemy of good. And some documentation\nseems strictly better than no documentation.\n\nThe transaction documentation could definitely be better. However, the\ntransaction code and transaction semantics are a hot mess and it is\nincredibly difficult to read and reason about. I think the only reasonable\nway we document and validate the documentation of transactions is by\nrefactoring the code to actually be readable and document what we learn\nalong the way.\n\nI started writing these docs several months ago, before the shared hgrc\nwork started. So the documentation is missing details about this feature\nas well. But that's an experimental feature. Hopefully we can add details\nof this feature to these docs before that feature stabilizes.","testPlan":"","lineCount":"535","dependsOn":[],"reviewers":["baymax"],"ccs":["marmoute","mharbison72","joerg.sonnenberger","mercurial-patches"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"164484","dateCreated":"1621935150","dateModified":"1621935150"},{"type":"reject","author":"baymax","id":"164483","dateCreated":"1621935150","dateModified":"1621935150"},{"type":"comment","comment":"(That patch is a bit daunting to review, maybe having each section in their own patch would help to process them in smaller piece)","author":"marmoute","id":"145580","dateCreated":"1608629821","dateModified":"1608629821"},{"type":"inline","comment":"> .hg\/hgrc is an exception here. Any others?\n\nI can't think of any writable examples, but the strip backups are maybe a read-only exception.","replyTo":"139506","isNewFile":"1","line":"5","lineLength":"0","path":"mercurial\/helptext\/internals\/repolayout.txt","diffId":"23424","author":"mharbison72","id":"139829","dateCreated":"1605159117","dateModified":"1605159117"},{"type":"inline","comment":"The inline -> external storage for revlog files should be documented as a special case here. I'm not even sure if the current logic is fully correct for that...","replyTo":null,"isNewFile":"1","line":"339","lineLength":"0","path":"mercurial\/helptext\/internals\/store-revlog.txt","diffId":"23424","author":"joerg.sonnenberger","id":"139515","dateCreated":"1604782575","dateModified":"1604782575"},{"type":"inline","comment":"As discussed earlier on IRC, I think the \"cache\" file property is currently hard-wired to 0 with no interface to set it to 1?","replyTo":null,"isNewFile":"1","line":"330","lineLength":"0","path":"mercurial\/helptext\/internals\/store-revlog.txt","diffId":"23424","author":"joerg.sonnenberger","id":"139514","dateCreated":"1604782575","dateModified":"1604782575"},{"type":"inline","comment":"See above.","replyTo":null,"isNewFile":"1","line":"191","lineLength":"0","path":"mercurial\/helptext\/internals\/store-revlog.txt","diffId":"23424","author":"joerg.sonnenberger","id":"139513","dateCreated":"1604782575","dateModified":"1604782575"},{"type":"inline","comment":"Byte value of 0 is not possible?","replyTo":null,"isNewFile":"1","line":"131","lineLength":"0","path":"mercurial\/helptext\/internals\/store-revlog.txt","diffId":"23424","author":"joerg.sonnenberger","id":"139512","dateCreated":"1604782575","dateModified":"1604782575"},{"type":"inline","comment":"using inline storage?","replyTo":null,"isNewFile":"1","line":"44","lineLength":"0","path":"mercurial\/helptext\/internals\/store-revlog.txt","diffId":"23424","author":"joerg.sonnenberger","id":"139511","dateCreated":"1604782575","dateModified":"1604782575"},{"type":"inline","comment":"00manifest.i?","replyTo":null,"isNewFile":"1","line":"43","lineLength":"0","path":"mercurial\/helptext\/internals\/store-revlog.txt","diffId":"23424","author":"joerg.sonnenberger","id":"139510","dateCreated":"1604782575","dateModified":"1604782575"},{"type":"inline","comment":"Mention cache and wcache as placeholders at least? Any other important items?","replyTo":null,"isNewFile":"1","line":"69","lineLength":"0","path":"mercurial\/helptext\/internals\/repolayout.txt","diffId":"23424","author":"joerg.sonnenberger","id":"139509","dateCreated":"1604782575","dateModified":"1604782575"},{"type":"inline","comment":"Maybe \"unknown properties of the repository encoding\" instead of UB?","replyTo":null,"isNewFile":"1","line":"18","lineLength":"0","path":"mercurial\/helptext\/internals\/repolayout.txt","diffId":"23424","author":"joerg.sonnenberger","id":"139508","dateCreated":"1604782575","dateModified":"1604782575"},{"type":"inline","comment":"We try to read the content of the symlink? Not sure if documenting the reason for a symlink (atomic creation including content) makes sense here.","replyTo":null,"isNewFile":"1","line":"51","lineLength":"0","path":"mercurial\/helptext\/internals\/locks.txt","diffId":"23424","author":"joerg.sonnenberger","id":"139507","dateCreated":"1604782575","dateModified":"1604782575"},{"type":"inline","comment":".hg\/hgrc is an exception here. Any others?","replyTo":null,"isNewFile":"1","line":"5","lineLength":"0","path":"mercurial\/helptext\/internals\/repolayout.txt","diffId":"23424","author":"joerg.sonnenberger","id":"139506","dateCreated":"1604782575","dateModified":"1604782575"},{"type":"update","diffId":"23424","author":"indygreg","id":"139497","dateCreated":"1604778173","dateModified":"1604778173"}],"dateCreated":"1604778173","dateModified":"1621935150","status":"Needs Revision"},{"id":"9603","callsign":"HG","title":"branchmap: refactor revbranchmap and use it as topicmap [PoC]","author":"joerg.sonnenberger","summary":"","testPlan":"","lineCount":"201","dependsOn":[],"reviewers":["baymax"],"ccs":["pulkit","mercurial-patches"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"164481","dateCreated":"1621935149","dateModified":"1621935149"},{"type":"reject","author":"baymax","id":"164480","dateCreated":"1621935149","dateModified":"1621935149"},{"type":"update","diffId":"24819","author":"joerg.sonnenberger","id":"147387","dateCreated":"1610572212","dateModified":"1610572212"},{"type":"inline","comment":"Yes, but it is a breaking change for topic.","replyTo":"145194","isNewFile":"0","line":"599","lineLength":"0","path":"mercurial\/changelog.py","diffId":"24342","author":"joerg.sonnenberger","id":"145265","dateCreated":"1608322786","dateModified":"1608322786"},{"type":"inline","comment":"As mentioned in the review for the parent, doing a lookup here is expensive and should be avoided. The extra=None case is essentially only used for nullrev. The function name is not terribly good, `parsechangeset` or so would make a lot more sense in the generalized cache.","replyTo":"145196","isNewFile":"1","line":"599","lineLength":"0","path":"mercurial\/branchmap.py","diffId":"24342","author":"joerg.sonnenberger","id":"145264","dateCreated":"1608322786","dateModified":"1608322786"},{"type":"inline","comment":"Right, the primary goal of this PoC is to outline what changes are necessary and what the impact is for supporting more than just the branch mapping. It doesn't make sense as is since it is provided for the benefit out of currently out-of-tree target. So the goal is to get a consensus on whether the cache is useful enough for the topic extension and if it is, split this patch into smaller pieces, figure out a few details in the method naming (e.g. `branchinfo` is tight to the current functionality) in core and how to integrate the rest backwards compatible in the topic extension.","replyTo":"145192","isNewFile":"1","line":"547","lineLength":"0","path":"mercurial\/branchmap.py","diffId":"24342","author":"joerg.sonnenberger","id":"145263","dateCreated":"1608322786","dateModified":"1608322786"},{"type":"inline","comment":"Also, what does a caller passing extra as None is expecting here? It will be nice to not have this an optional argument.\n\nWe can also pass a rev\/node here and do `changelog.changelogrevision` thing in this function.","replyTo":null,"isNewFile":"1","line":"599","lineLength":"0","path":"mercurial\/branchmap.py","diffId":"24342","author":"pulkit","id":"145196","dateCreated":"1608320801","dateModified":"1608320801"},{"type":"comment","comment":">>! In D9603#145191, @pulkit wrote:\n> I like where this is headed. Thank you for doing this work. I can see this patch can be split into at least 3 different patches which will help speed up review.\n\n... of course when it's not a POC anymore.","author":"pulkit","id":"145195","dateCreated":"1608320801","dateModified":"1608320801"},{"type":"inline","comment":"This and related changes should be a separate patch.","replyTo":null,"isNewFile":"0","line":"599","lineLength":"0","path":"mercurial\/changelog.py","diffId":"24342","author":"pulkit","id":"145194","dateCreated":"1608320628","dateModified":"1608320628"},{"type":"inline","comment":"Probably we can have an interface for generic name-cache.","replyTo":null,"isNewFile":"1","line":"782","lineLength":"0","path":"mercurial\/branchmap.py","diffId":"24342","author":"pulkit","id":"145193","dateCreated":"1608320628","dateModified":"1608320628"},{"type":"inline","comment":"This movement of variables can be a separate patch and will be easy one to queue making this patch a bit lighter to review.","replyTo":null,"isNewFile":"1","line":"547","lineLength":"0","path":"mercurial\/branchmap.py","diffId":"24342","author":"pulkit","id":"145192","dateCreated":"1608320628","dateModified":"1608320628"},{"type":"comment","comment":"I like where this is headed. Thank you for doing this work. I can see this patch can be split into at least 3 different patches which will help speed up review.","author":"pulkit","id":"145191","dateCreated":"1608320628","dateModified":"1608320628"},{"type":"update","diffId":"24342","author":"joerg.sonnenberger","id":"144920","dateCreated":"1608212506","dateModified":"1608212506"},{"type":"comment","comment":"The proof of concept part is primarily that we can get the benefit with minimal refactoring of the existing rbc implementation. The actual use is a bit more complicated as the actual topicmap would be part of an extension and therefore hook up differently. But the interaction is much easier to understand like this, IMO.","author":"joerg.sonnenberger","id":"144900","dateCreated":"1608206805","dateModified":"1608206805"},{"type":"comment","comment":"While it's still POC, having some commit message on how we are tackling the problem will be helpful.","author":"pulkit","id":"144832","dateCreated":"1608203029","dateModified":"1608203029"},{"type":"update","diffId":"24309","author":"joerg.sonnenberger","id":"144731","dateCreated":"1608129915","dateModified":"1608129915"},{"type":"update","diffId":"24272","author":"joerg.sonnenberger","id":"144527","dateCreated":"1607981914","dateModified":"1607981914"}],"dateCreated":"1607981914","dateModified":"1621935149","status":"Needs Revision"},{"id":"9724","callsign":"HG","title":"ci: build python wheels","author":"danchr","summary":"The wheels are merely attached to the job as artifacts. We could\nupload them to Heptapod or PyPI, but that's left for a possible followup.","testPlan":"","lineCount":"40","dependsOn":[],"reviewers":["baymax"],"ccs":["marmoute","mercurial-patches"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"164478","dateCreated":"1621935148","dateModified":"1621935148"},{"type":"reject","author":"baymax","id":"164477","dateCreated":"1621935148","dateModified":"1621935148"},{"type":"inline","comment":"Should we have an image based on `uay.io\/pypa\/${PLATFORM}` with this installed instead ?","replyTo":null,"isNewFile":"1","line":"118","lineLength":"0","path":"contrib\/heptapod-ci.yml","diffId":"24869","author":"marmoute","id":"147981","dateCreated":"1610770832","dateModified":"1610770832"},{"type":"comment","comment":"Do we want to build the wheel for every changeset ? or only build \"nightly\" build from default? (and tags! for tags !)\n\nWhat value do you expect if we run them for everything ?","author":"marmoute","id":"147980","dateCreated":"1610770832","dateModified":"1610770832"},{"type":"comment","comment":":negative_squared_cross_mark: refresh by Heptapod after a failed CI run (:octopus: :heart:) https:\/\/foss.heptapod.net\/octobus\/mercurial-devel\/-\/pipelines\/16444","author":"baymax","id":"147682","dateCreated":"1610677121","dateModified":"1610677121"},{"type":"update","diffId":"24869","author":"baymax","id":"147681","dateCreated":"1610677121","dateModified":"1610677121"},{"type":"update","diffId":"24715","author":"danchr","id":"146792","dateCreated":"1610453265","dateModified":"1610453265"}],"dateCreated":"1610453265","dateModified":"1621935148","status":"Needs Revision"},{"id":"9878","callsign":"HG","title":"revlog: initial version of phash index [POC]","author":"joerg.sonnenberger","summary":"Integration is still somewhat hackish, but a reasonable start for a PoC.\nComparing it to Rust is not entirely fair as the additional Python\nfunction in between dominates the runtime. The generator is pure Python\nat the moment and at least a factor of 25 slower than the comparable C\nextension. No fallback path for hash function yet to a real universal\nhash (as opposed to just assuming the node hash is well distributed\nenough). Most interesting baseline: pure Python lookup via the hash\nfunction is a factor of 20 slower than the current dictionary lookup.\nThe index generation takes 37s for 2 * 570k revisions (manifest +\nchangelog). Further testing to measure the incremental cache update cost\nis necessary, since initial testing shows a negative cost overall. It\ncan be estimated to be bound by ~65ms on the test platform.","testPlan":"","lineCount":"428","dependsOn":[],"reviewers":["indygreg","baymax"],"ccs":["mercurial-patches"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"164472","dateCreated":"1621935145","dateModified":"1621935145"},{"type":"reject","author":"baymax","id":"164471","dateCreated":"1621935145","dateModified":"1621935145"},{"type":"update","diffId":"25275","author":"joerg.sonnenberger","id":"149622","dateCreated":"1611694889","dateModified":"1611694889"}],"dateCreated":"1611694889","dateModified":"1621935146","status":"Needs Revision"},{"id":"9848","callsign":"HG","title":"fastexport: committer name should not be quoted","author":"roy","summary":"","testPlan":"","lineCount":"34","dependsOn":[],"reviewers":["baymax"],"ccs":["durin42","Alphare","joerg.sonnenberger","mercurial-patches"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"164475","dateCreated":"1621935146","dateModified":"1621935146"},{"type":"reject","author":"baymax","id":"164474","dateCreated":"1621935146","dateModified":"1621935146"},{"type":"comment","comment":"So if I send an email, using thunderbird, 9 folders or gmail and look at the email source the email name is not quoted.\nAll I ask is that hg behaves the same way. That should not be took much to ask?","author":"roy","id":"149357","dateCreated":"1611530196","dateModified":"1611530196"},{"type":"comment","comment":">>! In D9848#149355, @joerg.sonnenberger wrote:\n> Horrible parsing code, but not relevant for here. I gave the reasons why the original code used \"\", but I don't care either way if git doesn't fall apart anymore than already does when an address is not pretending to be a mail.\n\nYou gave your reasons, but I still cannot find any reference to git fast-import spec respecting any RFC formatting as per email address quoting.\nI quoted the spec where it says it takes it free-form, which describes what the code does.\n\n>>! In D9848#149232, @joerg.sonnenberger wrote:\n> The output is entirely valid according to the git format specification.\n\nYes, the output is valid in that it's free form, but you have forced quoted where none should be.\nYou might as well put more garbage in there and it's still valid, but it's not correct.","author":"roy","id":"149356","dateCreated":"1611530051","dateModified":"1611530051"},{"type":"comment","comment":"Horrible parsing code, but not relevant for here. I gave the reasons why the original code used \"\", but I don't care either way if git doesn't fall apart anymore than already does when an address is not pretending to be a mail.","author":"joerg.sonnenberger","id":"149355","dateCreated":"1611529365","dateModified":"1611529365"},{"type":"comment","comment":"Finds the author command\nhttps:\/\/github.com\/git\/git\/blob\/7f7ebe054af6d831b999d6c2241b9227c4e4e08d\/builtin\/fast-import.c#L2689\n\nWhich sends the text after the command to parse_ident() here.\nhttps:\/\/github.com\/git\/git\/blob\/7f7ebe054af6d831b999d6c2241b9227c4e4e08d\/builtin\/fast-import.c#L1938\n\nFirst, it verifies there is an email address in angled brackets.\nThen it creates a string buffer based structure where it places the exact text from the start upto and including closing angled bracket of the email address.\nIt then verifies the date and appends it's interpretation of that as well.\n\nNow we go back to continue in the first function to actual use this data in the commit:\nhttps:\/\/github.com\/git\/git\/blob\/7f7ebe054af6d831b999d6c2241b9227c4e4e08d\/builtin\/fast-import.c#L2764\n\nSo basically it just stores what it's given from the parse_ident function.\nThere is no attempt to parse the users name to remove any quotation added.\n\nAs to the specification - where do you see the need to quote?\nAll I can find is this\n```Here <name> is the person\u2019s display name (for example \u201cCom M Itter\u201d) and <email> is the person\u2019s email address (\u201ccm@example.com\u201d). LT and GT are the literal less-than (\\x3c) and greater-than (\\x3e) symbols. These are required to delimit the email address from the other fields in the line. Note that <name> and <email> are free-form and may contain any sequence of bytes, except LT, GT and LF. <name> is typically UTF-8 encoded.```\nThe quotes here show the value, not that it's quoted - after all, email address uses <>, not \"\".","author":"roy","id":"149296","dateCreated":"1611348322","dateModified":"1611348400"},{"type":"comment","comment":"The basic concern I have here is that I have stepped on git's toes here before and the field is nowhere near as free text as it is supposed to be according to the specification. So any change should at least double check what the git code is actually doing, because it doesn't do the same as the documentation from what I have seen. Case in point is the data handling, where git does distingiush between +0 and -0.","author":"joerg.sonnenberger","id":"149263","dateCreated":"1611346830","dateModified":"1611346830"},{"type":"comment","comment":"Should we add a test that, if git-fast-import is available, actually tries the import and verifies that things look reasonable?","author":"durin42","id":"149262","dateCreated":"1611345352","dateModified":"1611345352"},{"type":"comment","comment":"So just for kicks I did hg fastexport on my dhcpcd repo where the author names look fine.\nI then did hg fastimport (3rd party plugin) on the resultant fast-import file generated from the above.\n\nAnd hg also displayed \"Roy Marples\" <roy@marples.name> which again looks wrong.","author":"roy","id":"149236","dateCreated":"1611328019","dateModified":"1611328019"},{"type":"comment","comment":"Using git to create a fast-import, the comitter is never quoted.\nAgain, using git to import a quoted comitter name, preserves the quotes.\nUsing git log to display the import, the comitters name appears as \"Roy Marples\" <roy@marples.name> which just looks wrong.\n\nOther systems that creat a fast-import file such as Fossil don't quote either.\n\nWhile you might not see any reason to change this as per the specification which I can't argue with, no existing tooling other than hg fastexport actually quotes or understands quotes.\n\nSo @joerg.sonnenberger I respectfully ask why we need to quote here? I see no reason to.","author":"roy","id":"149235","dateCreated":"1611327043","dateModified":"1611327043"},{"type":"comment","comment":"The output is entirely valid according to the git format specification. It is also entirely valid under the formatting rules for email addresses, which was supposed to be the origin of this identifiers. As such, I see no reason to change anything.","author":"joerg.sonnenberger","id":"149232","dateCreated":"1611325562","dateModified":"1611325562"},{"type":"comment","comment":"@joerg.sonnenberger is there any way that this is not right?","author":"Alphare","id":"149219","dateCreated":"1611321520","dateModified":"1611321520"},{"type":"update","diffId":"25208","author":"roy","id":"149133","dateCreated":"1611282531","dateModified":"1611282531"}],"dateCreated":"1611282531","dateModified":"1621935146","status":"Needs Revision"},{"id":"10709","callsign":null,"title":"'guide' web page updates - remove stale bitbucket references","author":"jhein","summary":"The 'Guide' web page has stale references to bitbucket. The attached patch against the hg-website repo takes a pass at an update.\n\n\n Remove stale bitbucket refs. Some spelling updates.\n \n BitBucket dropped support for mercurial repos in 2020. Fix stale references\n to it in favor of more generic language about other hosting services\n (and point to a curated list on the wiki).\n\n\nAdded smf (current website repo meister)\n\n\nSee also [[ https:\/\/bz.mercurial-scm.org\/show_bug.cgi?id=6518 | issue 6518 ]]","testPlan":"","lineCount":"93","dependsOn":[],"reviewers":["smf"],"ccs":[],"actions":[{"type":"update","diffId":"27910","author":"jhein","id":"163088","dateCreated":"1620953075","dateModified":"1620953075"}],"dateCreated":"1620953075","dateModified":"1620953131","status":"Needs Review"},{"id":"10082","callsign":"HG","title":"tags: redo .hgtags file node cache to work more like the revbranchcache","author":"joerg.sonnenberger","summary":"Computing tags requires parsing .hgtags for all heads. Mercurial\ntherefore keeps a cache to efficiently find the .hgtags version of a\nrevision without having to parse the manifest, but this cache is\ncomputed lazily and often incomplete.\n\nThe new implementation of the test works a lot more like the\nrevbranchcache and updates the cache in two stages:\n(1) When a new changeset is added, check if .hgtags is touched. The\ncommon case is that it didn't change and it is therefore inherited from\nthe parent. Now the parent might not be fully resolved yet (missing\nmanifest), so just keep a dictionary mapping to the parent revision that\npotentially touched it.\n(2) At the end of the transaction, resolve entries before writing the\ncache to disk. At this point, manifests are all known, so they can be\nparsed as necessary. The fast path here is reading just the delta, but\nthis doesn't necessarily answer the question, since the delta could have\nbeen to a non-parent.\n\nIf the cache logic hits an invalid or missing node, it will recheck all\nnodes. This is a bit more expensive, but simplifies the logic and avoids\nrecursions. This penalty is normally hit only once, but read-only\nclients should run debugupdatecaches once and after strips. The\nrewritten version no longer uses a separate missing item. This matters\nonly if a node with 32bit leading nulls exist other than the nullid, but\nthat is as likely as 32bit leading ones with the old code.\n\nExtend verification has the .hgtags file node at least exists. It\ndoesn't create a measurable difference for the rebuild time for a tag\nheavy repository.\n\nThe code structure of the tag prepares for mmap access to the cache\nfile. The only in-place operation is append and that verifies the old\nfile size and is only used if nothing else changed.","testPlan":"","lineCount":"1565","dependsOn":[],"reviewers":["Alphare"],"ccs":["Alphare","pulkit","marmoute","mercurial-patches"],"actions":[{"type":"comment","comment":"Delayed for now as it doesn't work with the broken changelog.files and needs more efficient manifest logic first.","author":"joerg.sonnenberger","id":"159299","dateCreated":"1618919148","dateModified":"1618919148"},{"type":"plan-changes","author":"joerg.sonnenberger","id":"159298","dateCreated":"1618919148","dateModified":"1618919148"},{"type":"comment","comment":"What if we use a different file ? This would allow us to use a different semantic an adjusted plan for a smoother transition.","author":"marmoute","id":"157480","dateCreated":"1617994455","dateModified":"1617994455"},{"type":"inline","comment":"Maybe a `ProgrammingError` then ? or a dedicated ConsistencyError ? The current message in a high level exception class intended for the user (`Abort`), but is neither understandable by normal user nor actionnable by anyone. That is not great.","replyTo":"157431","isNewFile":"1","line":"816","lineLength":"0","path":"mercurial\/tags.py","diffId":"26738","author":"marmoute","id":"157479","dateCreated":"1617993973","dateModified":"1617993973"},{"type":"inline","comment":"They can be files that should be in the `files` field and are not. See https:\/\/bz.mercurial-scm.org\/show_bug.cgi?id=6219 for details.","replyTo":"157430","isNewFile":"1","line":"790","lineLength":"0","path":"mercurial\/tags.py","diffId":"26738","author":"marmoute","id":"157478","dateCreated":"1617993973","dateModified":"1617993973"},{"type":"inline","comment":"What about getting explicite `getfnode_node(\u2026)` in addition to a revnum only `getfnode(\u2026)`\n\n(not too important)","replyTo":"157429","isNewFile":"1","line":"763","lineLength":"2","path":"mercurial\/tags.py","diffId":"26738","author":"marmoute","id":"157477","dateCreated":"1617993973","dateModified":"1617993973"},{"type":"comment","comment":">>! In D10082#157428, @joerg.sonnenberger wrote:\n>>>! In D10082#157189, @marmoute wrote:\n>> What happens in the stream clone case ? Or during the transition from older to newer client ? streaming content from an older clone will not contains a fully up to date cache, and existing repository neither. How are we dealing with this ?\n>> \n>> You mention the need to update the cache after stripping, but I don't see such change in the code. am I missing something ?\n> \n> The cache will fix up itself when it detects missing entries.\n\nWhat does \"fix up itself\" involve here ? fixing the one missing entry ? or triggering a full computation, taking possibly minutes ?\n\n> This can take a moment and won't persist for true read-only repositories (since they are read-only). That's why there is a note in the release notes. It is note worthy as the case can be more expensive than before for (very) large repositories.\n\nI am a bit worried about that, because people don't read the release note and upgrade has a good chance to introduce some cripplying performance for unsuspecting user of larger repositories :-\/\n\n> I have plans to revisit the strip handling at least for modern clients to do the right thing in first place, but will be separate and also cover rev-branch-cache.\n\nThat sounds fine, strip is already a slow operation.\n","author":"marmoute","id":"157476","dateCreated":"1617993973","dateModified":"1617993973"},{"type":"comment","comment":">>! In D10082#157382, @marmoute wrote:\n> Do you have any performance number for that update ? for example the time we need to do that full some known large repositories, and the impact on a clone ?\n\nA full cache rebuild clocks at around 45s for my NetBSD src test repo with 950k revisions. That cost is dominated by the changelog parsing, so number of hgtags revisions doesn't matter for that part. There would be an additional pass reading those manifest (deltas), but I found that one to be negligible at least for the tag heavy repos I found. I didn't specifically measure clone, because I don't expect it to be significant. The changelog is already parsed at that point and the computations are otherwise fairly cheap.\n\n> How do you deal with repository corruption ? (for example if some old revision reference some missing hgtags ?)\n\nThere is a fast path for adding missing records beyond the end of the index. When asking about a revision beyond the current end of the cache, it just tries the forward computation. As long as the existing entries are all valid, only new revisions are touched. That is essentially the fix-up missed updates from older hg versions.\nWhen looking up an existing entry in the cache, `_validaterecord` checks that the truncated node match and that the filenode exists. If either is wrong, the cache is completely re-validated.","author":"joerg.sonnenberger","id":"157438","dateCreated":"1617968432","dateModified":"1617968432"},{"type":"inline","comment":"This is basically just an explicit sanity check at this point. It can be triggered only by broken revlogs, e.g. missing parent or parents not sorted before their children. I'd expect that to fall badly in other places, too. So I'm somewhat reluctant to add anything more here.","replyTo":"157192","isNewFile":"1","line":"816","lineLength":"0","path":"mercurial\/tags.py","diffId":"26738","author":"joerg.sonnenberger","id":"157431","dateCreated":"1617963283","dateModified":"1617963283"},{"type":"inline","comment":"In what way? If the basic \"files (potentially) touched\" is wrong, a lot of places in the tree are going to be failing. I'm aware that there are false positives, but those don't matter.","replyTo":"157191","isNewFile":"1","line":"790","lineLength":"0","path":"mercurial\/tags.py","diffId":"26738","author":"joerg.sonnenberger","id":"157430","dateCreated":"1617963283","dateModified":"1617963283"},{"type":"inline","comment":"The function is used internally where we have the choice and externally, where it is a mix of box. `fnoderevs` would easily be changed to operate on nodes, `_readtagcache` not so much, I think.","replyTo":"157190","isNewFile":"1","line":"763","lineLength":"2","path":"mercurial\/tags.py","diffId":"26738","author":"joerg.sonnenberger","id":"157429","dateCreated":"1617963283","dateModified":"1617963283"},{"type":"comment","comment":">>! In D10082#157189, @marmoute wrote:\n> What happens in the stream clone case ? Or during the transition from older to newer client ? streaming content from an older clone will not contains a fully up to date cache, and existing repository neither. How are we dealing with this ?\n> \n> You mention the need to update the cache after stripping, but I don't see such change in the code. am I missing something ?\n\nThe cache will fix up itself when it detects missing entries. This can take a moment and won't persist for true read-only repositories (since they are read-only). That's why there is a note in the release notes. It is note worthy as the case can be more expensive than before for (very) large repositories. I have plans to revisit the strip handling at least for modern clients to do the right thing in first place, but will be separate and also cover rev-branch-cache.","author":"joerg.sonnenberger","id":"157428","dateCreated":"1617963283","dateModified":"1617963283"},{"type":"comment","comment":"Do you have any performance number for that update ? for example the time we need to do that full some known large repositories, and the impact on a clone ?\n\nHow do you deal with repository corruption ? (for example if some old revision reference some missing hgtags ?)","author":"marmoute","id":"157382","dateCreated":"1617960259","dateModified":"1617960259"},{"type":"inline","comment":"Same feedback about `.files` here.","replyTo":null,"isNewFile":"1","line":"837","lineLength":"0","path":"mercurial\/tags.py","diffId":"26738","author":"marmoute","id":"157193","dateCreated":"1617938549","dateModified":"1617938549"},{"type":"inline","comment":"Can we get some more information about the error here ? liek what kind of invalid topology and for which revision ?","replyTo":null,"isNewFile":"1","line":"816","lineLength":"0","path":"mercurial\/tags.py","diffId":"26738","author":"marmoute","id":"157192","dateCreated":"1617938549","dateModified":"1617938549"},{"type":"inline","comment":"note that the `files` files can be wrong, and they are recurrent instance of it in the wild. The new sidedata storage that we use for copy tracing can fix this, but I don't think we can transparently expose it from the changelog revision abstraction.\n\nWe should at least get a XXX comment about it.","replyTo":null,"isNewFile":"1","line":"790","lineLength":"0","path":"mercurial\/tags.py","diffId":"26738","author":"marmoute","id":"157191","dateCreated":"1617938549","dateModified":"1617938549"},{"type":"inline","comment":"Question for a possible follow up: Should we make this revnum only ? I find low level function that accept both weird.","replyTo":null,"isNewFile":"1","line":"763","lineLength":"2","path":"mercurial\/tags.py","diffId":"26738","author":"marmoute","id":"157190","dateCreated":"1617938549","dateModified":"1617938549"},{"type":"comment","comment":"What happens in the stream clone case ? Or during the transition from older to newer client ? streaming content from an older clone will not contains a fully up to date cache, and existing repository neither. How are we dealing with this ?\n\nYou mention the need to update the cache after stripping, but I don't see such change in the code. am I missing something ?","author":"marmoute","id":"157189","dateCreated":"1617938549","dateModified":"1617938549"},{"type":"update","diffId":"26738","author":"joerg.sonnenberger","id":"157188","dateCreated":"1617932109","dateModified":"1617932109"},{"type":"inline","comment":"Right, I'm blind.","replyTo":"157038","isNewFile":"1","line":"703","lineLength":"0","path":"mercurial\/tags.py","diffId":"26497","author":"Alphare","id":"157040","dateCreated":"1617883577","dateModified":"1617883577"},{"type":"accept","author":"Alphare","id":"157039","dateCreated":"1617883577","dateModified":"1617883577"},{"type":"inline","comment":"Line 657ff in the new version.","replyTo":"156939","isNewFile":"1","line":"703","lineLength":"0","path":"mercurial\/tags.py","diffId":"26497","author":"joerg.sonnenberger","id":"157038","dateCreated":"1617879787","dateModified":"1617879787"},{"type":"inline","comment":"I'm not sure which docstring you're reffering to, so maybe it would help.\nSorry for the delay in review btw. :)","replyTo":"156644","isNewFile":"1","line":"703","lineLength":"0","path":"mercurial\/tags.py","diffId":"26497","author":"Alphare","id":"156939","dateCreated":"1617874933","dateModified":"1617874933"},{"type":"inline","comment":"The record format itself is described in the docstring of the class. Not sure if an explicit reference to that here really helps?","replyTo":"156627","isNewFile":"1","line":"703","lineLength":"0","path":"mercurial\/tags.py","diffId":"26497","author":"joerg.sonnenberger","id":"156644","dateCreated":"1617309824","dateModified":"1617309824"},{"type":"update","diffId":"26642","author":"joerg.sonnenberger","id":"156642","dateCreated":"1617309787","dateModified":"1617309787"},{"type":"inline","comment":"Possibly have a `_reset` method for this?","replyTo":null,"isNewFile":"1","line":"869","lineLength":"0","path":"mercurial\/tags.py","diffId":"26497","author":"Alphare","id":"156629","dateCreated":"1617286840","dateModified":"1617286840"},{"type":"inline","comment":"Doesn't that result in two lookups?","replyTo":null,"isNewFile":"1","line":"831","lineLength":"0","path":"mercurial\/tags.py","diffId":"26497","author":"Alphare","id":"156628","dateCreated":"1617286840","dateModified":"1617286840"},{"type":"inline","comment":"Could you add some comments about what we're comparing here? I understand we can't use a `namedtuple` (or anything readable) because Python, but this makes it hard to reason about the structure of `record` and why we're always splitting around `4`.","replyTo":null,"isNewFile":"1","line":"703","lineLength":"0","path":"mercurial\/tags.py","diffId":"26497","author":"Alphare","id":"156627","dateCreated":"1617286840","dateModified":"1617286840"},{"type":"inline","comment":"Could you please use a more descriptive variable name? To me, a small comment would go a long way on clarifying the semantics of some of the less obvious ones (all the more for when the code evolves).","replyTo":null,"isNewFile":"1","line":"678","lineLength":"0","path":"mercurial\/tags.py","diffId":"26497","author":"Alphare","id":"156626","dateCreated":"1617286840","dateModified":"1617286840"},{"type":"comment","comment":"The overall logic looks good (and simple to boot!) to me, but I have some comments about readability\/maintainability.","author":"Alphare","id":"156625","dateCreated":"1617286840","dateModified":"1617286840"},{"type":"comment","comment":"I am +1 on the idea. @marmoute you might want to have a look.","author":"pulkit","id":"155827","dateCreated":"1616093732","dateModified":"1616093732"},{"type":"update","diffId":"26497","author":"joerg.sonnenberger","id":"155825","dateCreated":"1616021428","dateModified":"1616021428"},{"type":"update","diffId":"26492","author":"joerg.sonnenberger","id":"155796","dateCreated":"1616011971","dateModified":"1616011971"},{"type":"update","diffId":"26185","author":"joerg.sonnenberger","id":"154051","dateCreated":"1615293092","dateModified":"1615293092"},{"type":"comment","comment":"There are still a few asserts to ensure internal consistency for now, but this should be mostly in shape now.","author":"joerg.sonnenberger","id":"153735","dateCreated":"1615051142","dateModified":"1615051142"},{"type":"update","diffId":"26117","author":"joerg.sonnenberger","id":"153719","dateCreated":"1615000665","dateModified":"1615000665"},{"type":"update","diffId":"26116","author":"joerg.sonnenberger","id":"153718","dateCreated":"1614995435","dateModified":"1614995435"},{"type":"update","diffId":"26010","author":"joerg.sonnenberger","id":"153096","dateCreated":"1614648944","dateModified":"1614648944"},{"type":"update","diffId":"26004","author":"joerg.sonnenberger","id":"153041","dateCreated":"1614619115","dateModified":"1614619115"}],"dateCreated":"1614619115","dateModified":"1618919148","status":"Changes Planned"},{"id":"7295","callsign":"HG","title":"pytype: add a (very slow) test that executes pytype","author":"durin42","summary":"This doesn't actually pass yet, but I wanted to share it early so\nothers can play with pytype.","testPlan":"","lineCount":"38","dependsOn":["7384"],"reviewers":["indygreg","marmoute"],"ccs":["quark","marmoute","mharbison72","dlax","indygreg","mjpieters","mercurial-devel"],"actions":[{"type":"comment","comment":"According to IRC discussion with Augie, this is not ready yet.","author":"marmoute","id":"126169","dateCreated":"1587148569","dateModified":"1587148569"},{"type":"reject","author":"marmoute","id":"126168","dateCreated":"1587148569","dateModified":"1587148569"},{"type":"comment","comment":"> No, initially because I'd never heard of it, but now because I don't want to deal with ocaml. :)\n\nThe `pip install` version ships with a pre-compiled binary so an ocaml compiler is not needed.\n\n> I'm dubious that it's doing anywhere near the checking of pytype if it manages to run to completion without errors. What does the output look like?\n\nGood question. I wasn't aware about the differences. I read pytype's README and the examples apply to pyre too. Pytype does type inference while pyre only checks functions that already have type annotations.\n\n\nPyre does complete ([output](https:\/\/bpaste.net\/7JCQ)). I wasn't able to get pytype past 44\/251 ([output](https:\/\/bpaste.net\/CLEQ)). For files with type annotations like `mail.py`, it seems pyre output is useful:\n\n```\n# on commit d844202324924919bc517691052d39c520e077eb\nmercurial\/mail.py:57:4 Inconsistent override [15]: `mail.STARTTLS.starttls` overrides method defined in `smtplib.SMTP` inconsistently. The overriding method is not annotated but should return a subtype of `typing.Tuple[int, bytes]`.\nmercurial\/mail.py:387:22 Incompatible variable type [9]: charsets is declared to have type `List[str]` but is used as type `None`.\nmercurial\/mail.py:392:28 Incompatible parameter type [6]: Expected `bytes` for 2nd anonymous parameter to call `_encode` but got `Union[bytes, str]`.\nmercurial\/mail.py:394:33 Incompatible parameter type [6]: Expected `bytes` for 1st anonymous parameter to call `encoding.strfromlocal` but got `Union[bytes, str]`.\nmercurial\/mail.py:397:35 Incompatible variable type [9]: charsets is declared to have type `List[str]` but is used as type `None`.\nmercurial\/mail.py:399:4 Incompatible variable type [9]: addr is declared to have type `str` but is used as type `bytes`.\nmercurial\/mail.py:402:30 Incompatible parameter type [6]: Expected `typing.Optional[str]` for 1st anonymous parameter to call `str.split` but got `bytes`.\nmercurial\/mail.py:405:8 Incompatible variable type [9]: addr is declared to have type `str` but is used as type `bytes`.\nmercurial\/mail.py:414:63 Incompatible parameter type [6]: Expected `bytes` for 1st anonymous parameter to call `encoding.strfromlocal` but got `str`.\nmercurial\/mail.py:417:31 Incompatible variable type [9]: charsets is declared to have type `List[str]` but is used as type `None`.\nmercurial\/mail.py:426:30 Incompatible variable type [9]: charsets is declared to have type `List[str]` but is used as type `None`.\nmercurial\/mail.py:446:22 Incompatible variable type [9]: charsets is declared to have type `List[str]` but is used as type `None`.\nmercurial\/mail.py:499:52 Incompatible parameter type [6]: Expected `Union[email.header.Header, str]` for 1st anonymous parameter to call `email.header.decode_header` but got `Union[bytes, email.header.Header]`.\n```\n\nIt seems to me that a combined approach might be interesting - use pytype to generate `pyi` files and pyre for faster checking.","author":"quark","id":"118882","dateCreated":"1580500731","dateModified":"1580500803"},{"type":"comment","comment":">>! In D7295#118785, @quark wrote:\n> Have `pyre` been considered?\n\nNo, initially because I'd never heard of it, but now because I don't want to deal with ocaml. :)\n\n> It seems `pyre` only takes 10 seconds to check all the `.py` files.\n> \n> EDIT: 10s on a machine with many CPU cores. 1 minute on laptop.\n\nI'm dubious that it's doing anywhere near the checking of pytype if it manages to run to completion without errors. What does the output look like?","author":"durin42","id":"118820","dateCreated":"1580483967","dateModified":"1580483967"},{"type":"comment","comment":"Have `pyre` been considered? It seems `pyre` only takes 10 seconds to check all the `.py` files.\n\nEDIT: 10s on a machine with many CPU cores. 1 minute on laptop.","author":"quark","id":"118785","dateCreated":"1580447745","dateModified":"1580449193"},{"type":"comment","comment":"This seems useful, and the stabilisation seems to take a long while. Maybe we could take it in its current state (with \"expected\" broken output) and iterate from there. With the test in the repo.\n\nWhat do you all think ?","author":"marmoute","id":"118743","dateCreated":"1580409284","dateModified":"1580409284"},{"type":"comment","comment":">>! In D7295#110254, @mharbison72 wrote:\n>>>! In D7295#107482, @indygreg wrote:\n>> Since type checking is slow (but there are state files we can reuse to speed things up), we'll need to figure out how to make this work in CI. But I have no doubt we can figure something out. Out of curiosity, how long does pytype take to run in a clean source directory, without any state files?\n> \n> It takes 15-20 minutes on a 2018 Mac mini. In addition to the disabled files here, I've disabled:\n> \n> mercurial\/httppeer.py\n> mercurial\/repoview.py\n> mercurial\/localrepo.py\n> mercurial\/revlog.py\n> mercurial\/merge.py\n> mercurial\/testing\/storage.py\n> \n> But I've also added back these, and sprinkled various disable comments around:\n> \n> mercurial\/bundlerepo.py\n> mercurial\/error.py\n> mercurial\/exchange.py\n> mercurial\/policy.py\n> mercurial\/pycompat.py\n> mercurial\/scmwindows.py\n> mercurial\/windows.py\n> mercurial\/wireprotoframing.py\n> \n> Even with the state files, it seems to take 10-15 minutes or so.\n\nOoh, can you send your extra suppressions? For the most part I've been tackling this as a side project when I'm waiting on compiles.\n\nAs to doing individual files: that's well and good, and might be a viable approach for mypy. That said, my sense has been that mypy is faster and significantly less useful, since we don't get cross-file analysis of what's going on. I _think_ pytype gets faster as we add more annotations, so my rough thought thus far as been to try and get some subset of the codebase clean, transitively, and then try to start stamping some types on important functions and interfaces to constrain things. Where I'd _really_ like to get is to be able to migrate the `@command` decorators and friends to use strings instead of bytes, and be able to recommend typechecking as a way for extension authors to clean things up, but that'll take a while.","author":"durin42","id":"110437","dateCreated":"1574531296","dateModified":"1574531296"},{"type":"comment","comment":">>! In D7295#107482, @indygreg wrote:\n> Since type checking is slow (but there are state files we can reuse to speed things up), we'll need to figure out how to make this work in CI. But I have no doubt we can figure something out. Out of curiosity, how long does pytype take to run in a clean source directory, without any state files?\n\nIt takes 15-20 minutes on a 2018 Mac mini. In addition to the disabled files here, I've disabled:\n\n mercurial\/httppeer.py\n mercurial\/repoview.py\n mercurial\/localrepo.py\n mercurial\/revlog.py\n mercurial\/merge.py\n mercurial\/testing\/storage.py\n\nBut I've also added back these, and sprinkled various disable comments around:\n\n mercurial\/bundlerepo.py\n mercurial\/error.py\n mercurial\/exchange.py\n mercurial\/policy.py\n mercurial\/pycompat.py\n mercurial\/scmwindows.py\n mercurial\/windows.py\n mercurial\/wireprotoframing.py\n\nEven with the state files, it seems to take 10-15 minutes or so.","author":"mharbison72","id":"110254","dateCreated":"1574462605","dateModified":"1574462605"},{"type":"update","diffId":"18242","author":"durin42","id":"109676","dateCreated":"1574187225","dateModified":"1574187225"},{"type":"inline","comment":"Needs a trailing slash here.","replyTo":null,"isNewFile":"1","line":"22","lineLength":"0","path":"tests\/test-check-pytype.t","diffId":"18104","author":"mharbison72","id":"109670","dateCreated":"1574180889","dateModified":"1574180889"},{"type":"update","diffId":"18104","author":"durin42","id":"108811","dateCreated":"1573765830","dateModified":"1573765830"},{"type":"update","diffId":"18072","author":"durin42","id":"108536","dateCreated":"1573703500","dateModified":"1573703500"},{"type":"comment","comment":"This can't land per commit message, so setting status accordingly.\n\nI'm extremely supportive of adding type checking, whether it be pytype or mypy. I don't think it matters much. And TBH I wouldn't be surprised if we end up with both once we drop Python 2 support and start using inline annotations heavily!\n\nAs for how to start testing, I think we should do this like Python 3 and try to make individual files \"clean.\" Maintain a list of clean files and we ratchet from there.\n\nSince type checking is slow (but there are state files we can reuse to speed things up), we'll need to figure out how to make this work in CI. But I have no doubt we can figure something out. Out of curiosity, how long does pytype take to run in a clean source directory, without any state files?","author":"indygreg","id":"107482","dateCreated":"1573231954","dateModified":"1573231954"},{"type":"reject","author":"indygreg","id":"107481","dateCreated":"1573231954","dateModified":"1573231954"},{"type":"update","diffId":"17665","author":"durin42","id":"106664","dateCreated":"1573081192","dateModified":"1573081192"}],"dateCreated":"1573081192","dateModified":"1618183492","status":"Needs Revision"},{"id":"10282","callsign":"HG","title":"heptapod-ci: add jobs to test Mercurial using re2","author":"marmoute","summary":"They are multiple library providing a re2 module and they were broken with 5.7,\nso we add some (smaller) job to test them using new images.","testPlan":"","lineCount":"34","dependsOn":[],"reviewers":[],"ccs":["mercurial-patches"],"actions":[{"type":"comment","comment":"This I wanted to sent its parent\u2026","author":"marmoute","id":"156459","dateCreated":"1616971933","dateModified":"1616971933"},{"type":"plan-changes","author":"marmoute","id":"156458","dateCreated":"1616971933","dateModified":"1616971933"},{"type":"update","diffId":"26614","author":"marmoute","id":"156448","dateCreated":"1616970086","dateModified":"1616970086"}],"dateCreated":"1616970086","dateModified":"1616971933","status":"Changes Planned"},{"id":"7384","callsign":"HG","title":"commands: necessary annotations and suppresssions to pass pytype","author":"durin42","summary":"As with other places, there are some places where our types are just\ntoo complicated for pytype, so we put some suppressions in place.","testPlan":"","lineCount":"24","dependsOn":["7296"],"reviewers":["dlax","marmoute","baymax"],"ccs":["mercurial-patches","marmoute","dlax","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"128582","dateCreated":"1591637694","dateModified":"1591637694"},{"type":"reject","author":"baymax","id":"128581","dateCreated":"1591637694","dateModified":"1591637694"},{"type":"comment","comment":"There don't seems to be any remaininf feedback on this.","author":"marmoute","id":"120850","dateCreated":"1581668481","dateModified":"1581668481"},{"type":"accept","author":"marmoute","id":"120849","dateCreated":"1581668481","dateModified":"1581668481"},{"type":"inline","comment":"I think this comment should be removed since the `# pytype: disable` got removed in the last version of the diff.","replyTo":null,"isNewFile":"1","line":"4741","lineLength":"0","path":"mercurial\/commands.py","diffId":"18171","author":"dlax","id":"118745","dateCreated":"1580412376","dateModified":"1580412376"},{"type":"comment","comment":">>! In D7384#118739, @marmoute wrote:\n> What's up on this ? It seemed on a good track, but I don't think it landed. @dlax I think you offer to use a context manager got a warm welcome, I would says, go ahead with it.\n\nThe context manager got in through D7430.","author":"dlax","id":"118744","dateCreated":"1580412376","dateModified":"1580412376"},{"type":"comment","comment":"What's up on this ? It seemed on a good track, but I don't think it landed. @dlax I think you offer to use a context manager got a warm welcome, I would says, go ahead with it.","author":"marmoute","id":"118739","dateCreated":"1580409172","dateModified":"1580409172"},{"type":"update","diffId":"18171","author":"durin42","id":"109261","dateCreated":"1573854923","dateModified":"1573854923"},{"type":"inline","comment":"`revs` is always a `smartset.baseset` per af9c73f26371 so there should be no attribute error. Or is it because `logcmdutil.getlinerangerevs()` has no type annotation (whereas `logcmdutil.getrevs()` has some)?","replyTo":null,"isNewFile":"1","line":"4742","lineLength":"0","path":"mercurial\/commands.py","diffId":"18162","author":"dlax","id":"109205","dateCreated":"1573839647","dateModified":"1573839647"},{"type":"update","diffId":"18162","author":"durin42","id":"109201","dateCreated":"1573839083","dateModified":"1573839083"},{"type":"comment","comment":"I still want to keep the annotations I added. :)","author":"durin42","id":"109194","dateCreated":"1573838661","dateModified":"1573838661"},{"type":"comment","comment":"D7430 makes this changes unnecessary I think.","author":"dlax","id":"109165","dateCreated":"1573816122","dateModified":"1573816122"},{"type":"reject","author":"dlax","id":"109163","dateCreated":"1573816122","dateModified":"1573816122"},{"type":"inline","comment":"By all means!","replyTo":"108589","isNewFile":"1","line":"1127","lineLength":"0","path":"mercurial\/commands.py","diffId":"18071","author":"durin42","id":"108819","dateCreated":"1573766153","dateModified":"1573766153"},{"type":"update","diffId":"18099","author":"durin42","id":"108777","dateCreated":"1573765800","dateModified":"1573765800"},{"type":"inline","comment":"This one is sad. I think this can be sorted out by replacing the `try:\/finally:` with a context manager. (Can send a patch, if it sounds good to you.)","replyTo":null,"isNewFile":"1","line":"1127","lineLength":"0","path":"mercurial\/commands.py","diffId":"18071","author":"dlax","id":"108589","dateCreated":"1573724725","dateModified":"1573724725"},{"type":"update","diffId":"18071","author":"durin42","id":"108529","dateCreated":"1573703495","dateModified":"1573703495"}],"dateCreated":"1573703495","dateModified":"1616437763","status":"Needs Revision"},{"id":"7296","callsign":"HG","title":"pycompat: kludge around pytype being confused by __new__","author":"durin42","summary":"Credit to Yuya for the idea of annotating the class as though it was a\ncallable. I honestly didn't expect this to work, but it does!\n\nWe annotate this awkwardly on a name alias of the type because putting\nthe annotation directly on the `class ...:` line as a comment breaks\nblack and I don't want to go down that rabbit hole.","testPlan":"","lineCount":"17","dependsOn":[],"reviewers":["indygreg","dlax"],"ccs":["marmoute","yuja","mjpieters","dlax","indygreg","mercurial-devel"],"actions":[{"type":"comment","comment":"I'd like to get back to pytyping all the things, but I can't justify spending more time on it. If someone else wants to push things forward I'll gladly provide some mentorship.","author":"durin42","id":"124131","dateCreated":"1584719973","dateModified":"1584719973"},{"type":"plan-changes","author":"durin42","id":"124130","dateCreated":"1584719973","dateModified":"1584719973"},{"type":"comment","comment":"This is the last series stuck at the bottom of yadda.\n\nIt feels like it is still a work in progress, @durin42 can you clarify the status of this and possibly move it out of need-review if it is still a work in progress ? ","author":"marmoute","id":"124053","dateCreated":"1584659695","dateModified":"1584659695"},{"type":"comment","comment":"The status of this is unclear ? Are we waiting on:\n\n1) a the right way to do it in our codebase?\n2) a fix in pytype?\n3) a fix in python?\n4) something else?","author":"marmoute","id":"118737","dateCreated":"1580409000","dateModified":"1580409000"},{"type":"comment","comment":">>! In D7296#109684, @dlax wrote:\n> Looking closer at the error above, it mentions `bytestr.__init__`, not `__new__` (and there is in fact no type annotation for `__new__` in [typeshed](https:\/\/github.com\/python\/typeshed\/blob\/34d68ab0a2117a08fa221d3a10884f35cacf2cdc\/stdlib\/2and3\/builtins.pyi#L559)). \n\nhttps:\/\/github.com\/python\/typeshed\/issues\/2630","author":"dlax","id":"109688","dateCreated":"1574194446","dateModified":"1574194446"},{"type":"inline","comment":"Now the `type: ` is missing, so the comment is ignored.\n\nAdding it, `pytype mercurial\/pycompat.py` gives:\n```\nmercurial\/pycompat.py\", line 305, in <module>: Invalid type comment: Callable[[Union[bytes, str]], bytestr] [invalid-type-comment]\n Name 'bytestr' is not defined\n```\nhence the kind of trick I suggested in my first comment on this line.","replyTo":null,"isNewFile":"1","line":"305","lineLength":"0","path":"mercurial\/pycompat.py","diffId":"18243","author":"dlax","id":"109687","dateCreated":"1574194206","dateModified":"1574194206"},{"type":"comment","comment":">>! In D7296#109683, @durin42 wrote:\n>>>! In D7296#109672, @dlax wrote:\n>> Sorry, still not ok afaict :\/\n> \n> So, I tried fixing this and it actually made things worse? dagparser.py no longer typechecks if I correct the syntax? Try the pytype invocation from the test at the end of the series and you'll see what I mean.\n\nOk, trying `pytype mercurial\/dagparser.py` I get a couple of those errors:\n```\nFile \"...\/mercurial\/dagparser.py\", line 172, in parsedag: Function bytestr.__init__ was called with the wrong arguments [wrong-arg-types]\n Expected: (self, ints: Iterable[int])\n Actually passed: (self, ints: str)\n```\n\nMy point was that we need to keep \"mercurial\/pycompat.py\" passing pytype before considering modules it depends on. Once the missing `type: ` is added and bytestr <-> _bytestr trick applied, it's okay but the error in dagparser.py persists...\nLooking closer at the error above, it mentions `bytestr.__init__`, not `__new__` (and there is in fact no type annotation for `__new__` in [typeshed](https:\/\/github.com\/python\/typeshed\/blob\/34d68ab0a2117a08fa221d3a10884f35cacf2cdc\/stdlib\/2and3\/builtins.pyi#L559)). So I suspect the \"Callable\" trick is not enough and we'd need a workaround similar to da925257 by @yuja . ","author":"dlax","id":"109686","dateCreated":"1574194206","dateModified":"1574194206"},{"type":"comment","comment":">>! In D7296#109672, @dlax wrote:\n> Sorry, still not ok afaict :\/\n\nSo, I tried fixing this and it actually made things worse? dagparser.py no longer typechecks if I correct the syntax? Try the pytype invocation from the test at the end of the series and you'll see what I mean.","author":"durin42","id":"109683","dateCreated":"1574187658","dateModified":"1574187658"},{"type":"update","diffId":"18243","author":"durin42","id":"109678","dateCreated":"1574187647","dateModified":"1574187647"},{"type":"inline","comment":"same here about missing `]`.","replyTo":null,"isNewFile":"1","line":"414","lineLength":"0","path":"mercurial\/pycompat.py","diffId":"18240","author":"dlax","id":"109674","dateCreated":"1574181559","dateModified":"1574181559"},{"type":"inline","comment":"`]` is still at the wrong place, I think. Should be `Callable[[Union[bytes, str]], bytestr]`.\nThen I still get the \"Name 'bytestr' is not defined\" error mentioned above.","replyTo":null,"isNewFile":"1","line":"305","lineLength":"0","path":"mercurial\/pycompat.py","diffId":"18240","author":"dlax","id":"109673","dateCreated":"1574181559","dateModified":"1574181559"},{"type":"comment","comment":"Sorry, still not ok afaict :\/","author":"dlax","id":"109672","dateCreated":"1574181559","dateModified":"1574181559"},{"type":"reject","author":"dlax","id":"109671","dateCreated":"1574181559","dateModified":"1574181559"},{"type":"update","diffId":"18240","author":"durin42","id":"109659","dateCreated":"1574180082","dateModified":"1574180082"},{"type":"comment","comment":"@durin42 I just queued most of the remaining patches in this series. This one still needs your attention, it appears.","author":"indygreg","id":"109571","dateCreated":"1574135272","dateModified":"1574135272"},{"type":"inline","comment":"A `]` is missing before `, bytestr`. Then, it's also missing `typing` imports.\nBut, even with this, I get:\n\n```\nInvalid type comment: Callable[[Union[bytes, str]], bytestr] [invalid-type-comment]\n Name 'bytestr' is not defined\n```\n\nI'm able to make this pass with:\n```\nbytestr = _bytestr\nbytestr = bytestr # type: Callable[[Union[bytes, str]], bytestr]\n```\n\n","replyTo":null,"isNewFile":"1","line":"294","lineLength":"0","path":"mercurial\/pycompat.py","diffId":"18170","author":"dlax","id":"109308","dateCreated":"1573896532","dateModified":"1573896532"},{"type":"reject","author":"dlax","id":"109307","dateCreated":"1573896532","dateModified":"1573896532"},{"type":"update","diffId":"18170","author":"durin42","id":"109260","dateCreated":"1573854911","dateModified":"1573854911"},{"type":"comment","comment":"black complains because inline comments have only one space before (esp. the first one produces a parse error).\nLGTM otherwise.","author":"dlax","id":"109206","dateCreated":"1573840061","dateModified":"1573840061"},{"type":"update","diffId":"18163","author":"durin42","id":"109203","dateCreated":"1573839171","dateModified":"1573839171"},{"type":"update","diffId":"18161","author":"durin42","id":"109198","dateCreated":"1573839068","dateModified":"1573839068"},{"type":"comment","comment":"Rather `class bytestr(bytes): # type: Callable[[Union[bytes, str], bytestr]` as @yuya suggested in D7380.","author":"dlax","id":"109159","dateCreated":"1573815818","dateModified":"1573815818"},{"type":"reject","author":"dlax","id":"109157","dateCreated":"1573815818","dateModified":"1573815818"},{"type":"comment","comment":"```\nclass bytestr(bytes): # type: (Union[bytes,str]) -> bytestr\n [...]\n```\n\nDoes this work?","author":"dlax","id":"108595","dateCreated":"1573729523","dateModified":"1573729523"},{"type":"update","diffId":"18066","author":"durin42","id":"108497","dateCreated":"1573703466","dateModified":"1573703466"},{"type":"comment","comment":"I'm going to mark for revisions until we know more so this doesn't show up in the reviewable list.","author":"indygreg","id":"107463","dateCreated":"1573231683","dateModified":"1573231683"},{"type":"reject","author":"indygreg","id":"107462","dateCreated":"1573231683","dateModified":"1573231683"},{"type":"comment","comment":"I've filed a bug with the pytype team, I'll report back.","author":"durin42","id":"106946","dateCreated":"1573142864","dateModified":"1573142864"},{"type":"comment","comment":"This one makes me sad because of potential performance regressions due to call overhead. I'd almost rather rip out Python 2 support rather than land this. But I could be convinced if pytypes is as cool as you say...\n\nIs there no way to annotate the types here without the call overhead? Could we do something like an `if False` trick to define a `def bytestr()` with the proper annotations? Surely there's got to be a way...","author":"indygreg","id":"106892","dateCreated":"1573115914","dateModified":"1573115914"},{"type":"update","diffId":"17672","author":"durin42","id":"106678","dateCreated":"1573082663","dateModified":"1573082663"}],"dateCreated":"1573082663","dateModified":"1615572742","status":"Changes Planned"},{"id":"9725","callsign":"HG","title":"ci: generate and report XML test results","author":"danchr","summary":"","testPlan":"","lineCount":"11","dependsOn":["9724"],"reviewers":["pulkit"],"ccs":["marmoute","mercurial-patches"],"actions":[{"type":"comment","comment":"This patch does not apply on current tip of default branch. Kindly rebase and resend.","author":"pulkit","id":"154246","dateCreated":"1615367720","dateModified":"1615367720"},{"type":"reject","author":"pulkit","id":"154245","dateCreated":"1615367720","dateModified":"1615367720"},{"type":"comment","comment":">>! In D9725#150991, @danchr wrote:\n>>>! In D9725#147983, @marmoute wrote:\n>> This looks fine, but could you describe a bit what this is suppose to achieve and maybe provide a link to an example ?\n> \n> It exposes the unit tests results to GitLab CI, for nice rendering. See for example this run: https:\/\/foss.heptapod.net\/octobus\/mercurial-devel\/-\/pipelines\/16444\/test_report\n> \n> You also get a summary in any merge request detailing any failed or fixed tests.\n\nho interresting, thanks.","author":"marmoute","id":"150999","dateCreated":"1612892642","dateModified":"1612892642"},{"type":"comment","comment":">>! In D9725#147983, @marmoute wrote:\n> This looks fine, but could you describe a bit what this is suppose to achieve and maybe provide a link to an example ?\n\nIt exposes the unit tests results to GitLab CI, for nice rendering. See for example this run: https:\/\/foss.heptapod.net\/octobus\/mercurial-devel\/-\/pipelines\/16444\/test_report\n\nYou also get a summary in any merge request detailing any failed or fixed tests.","author":"danchr","id":"150991","dateCreated":"1612892120","dateModified":"1612892120"},{"type":"comment","comment":"I am happy to push this and next one but they needs to be rebased on current tip of default branch.","author":"pulkit","id":"150718","dateCreated":"1612342885","dateModified":"1612342885"},{"type":"accept","author":"pulkit","id":"150137","dateCreated":"1611951322","dateModified":"1611951322"},{"type":"comment","comment":"This looks fine, but could you describe a bit what this is suppose to achieve and maybe provide a link to an example ?","author":"marmoute","id":"147983","dateCreated":"1610770973","dateModified":"1610770973"},{"type":"comment","comment":":negative_squared_cross_mark: refresh by Heptapod after a failed CI run (:octopus: :heart:) https:\/\/foss.heptapod.net\/octobus\/mercurial-devel\/-\/pipelines\/16444","author":"baymax","id":"147684","dateCreated":"1610677123","dateModified":"1610677123"},{"type":"update","diffId":"24870","author":"baymax","id":"147683","dateCreated":"1610677123","dateModified":"1610677123"},{"type":"update","diffId":"24716","author":"danchr","id":"146800","dateCreated":"1610453270","dateModified":"1610453270"}],"dateCreated":"1610453270","dateModified":"1615367720","status":"Needs Revision"},{"id":"9726","callsign":"HG","title":"ci: use parallel matrices","author":"danchr","summary":"","testPlan":"","lineCount":"100","dependsOn":["9725"],"reviewers":["pulkit"],"ccs":["marmoute","Alphare","mercurial-patches"],"actions":[{"type":"accept","author":"pulkit","id":"150139","dateCreated":"1611951359","dateModified":"1611951359"},{"type":"comment","comment":"This looks very nice, but please coordinate with @Alphare who have been writing important change in this area too. (orthogonal, but conflicting) ","author":"marmoute","id":"147985","dateCreated":"1610771021","dateModified":"1610771021"},{"type":"comment","comment":":negative_squared_cross_mark: refresh by Heptapod after a failed CI run (:octopus: :heart:) https:\/\/foss.heptapod.net\/octobus\/mercurial-devel\/-\/pipelines\/16444","author":"baymax","id":"147686","dateCreated":"1610677124","dateModified":"1610677124"},{"type":"update","diffId":"24871","author":"baymax","id":"147685","dateCreated":"1610677124","dateModified":"1610677124"},{"type":"update","diffId":"24717","author":"danchr","id":"146807","dateCreated":"1610453275","dateModified":"1610453275"}],"dateCreated":"1610453275","dateModified":"1611951359","status":"Accepted"},{"id":"9727","callsign":"HG","title":"ci: report status to phabricator on failures","author":"danchr","summary":"","testPlan":"","lineCount":"22","dependsOn":["9726"],"reviewers":["marmoute"],"ccs":["marmoute","mercurial-patches"],"actions":[{"type":"comment","comment":"phabricator is inconstistent when it comes to updating diff (and printing associated message). So I fear we would end up in situation where a comment would be made to make a Diff as part of a failing run, without it being replaced by a positive message once test pass.\n\nSo -1 on this until it is fixed or proved to not happen.","author":"marmoute","id":"147977","dateCreated":"1610770681","dateModified":"1610770681"},{"type":"reject","author":"marmoute","id":"147976","dateCreated":"1610770681","dateModified":"1610770681"},{"type":"comment","comment":":negative_squared_cross_mark: refresh by Heptapod after a failed CI run (:octopus: :heart:) https:\/\/foss.heptapod.net\/octobus\/mercurial-devel\/-\/pipelines\/16444","author":"baymax","id":"147688","dateCreated":"1610677126","dateModified":"1610677126"},{"type":"update","diffId":"24872","author":"baymax","id":"147687","dateCreated":"1610677126","dateModified":"1610677126"},{"type":"comment","comment":":negative_squared_cross_mark: refresh by Heptapod after a failed CI run (:octopus: :heart:) https:\/\/foss.heptapod.net\/octobus\/mercurial-devel\/-\/pipelines\/15994","author":"baymax","id":"146822","dateCreated":"1610457108","dateModified":"1610457108"},{"type":"update","diffId":"24719","author":"baymax","id":"146821","dateCreated":"1610457108","dateModified":"1610457108"},{"type":"update","diffId":"24718","author":"danchr","id":"146814","dateCreated":"1610453280","dateModified":"1610453280"}],"dateCreated":"1610453280","dateModified":"1610770681","status":"Needs Revision"},{"id":"9472","callsign":"HG","title":"testing phabricator encoding","author":"martinvonz","summary":"","testPlan":"","lineCount":"16","dependsOn":[],"reviewers":[],"ccs":["mharbison72","Alphare","mercurial-patches"],"actions":[{"type":"comment","comment":">>! In D9472#143491, @martinvonz wrote:\n>>>! In D9472#143442, @Alphare wrote:\n>> I'm honored to be the mojibake test. ;)\n> \n> :)\n> \n> @mharbison72: I'm not doing anything more with this test. Are you or should I drop this patch? I'll at least mark it \"Plan Changes\" for now.\n\nSorry, I missed this in the tsunami of emails. I won't have time to look before the freeze in all likelihood, but maybe then? I wish there was a way to add it to a TODO list so I don't lose it again.","author":"mharbison72","id":"147117","dateCreated":"1610512382","dateModified":"1610512382"},{"type":"comment","comment":">>! In D9472#143442, @Alphare wrote:\n> I'm honored to be the mojibake test. ;)\n\n:)\n\n@mharbison72: I'm not doing anything more with this test. Are you or should I drop this patch? I'll at least mark it \"Plan Changes\" for now.","author":"martinvonz","id":"143492","dateCreated":"1607361839","dateModified":"1607361839"},{"type":"plan-changes","author":"martinvonz","id":"143490","dateCreated":"1607361839","dateModified":"1607361839"},{"type":"comment","comment":"I'm honored to be the mojibake test. ;)","author":"Alphare","id":"143442","dateCreated":"1607336033","dateModified":"1607336033"},{"type":"update","diffId":"23896","author":"martinvonz","id":"142424","dateCreated":"1606808064","dateModified":"1606808064"}],"dateCreated":"1606808064","dateModified":"1610512382","status":"Changes Planned"},{"id":"9571","callsign":"HG","title":"debugsharesafe: recommend from `debugupgraderepo` and `help -e share -v`","author":"pulkit","summary":"Recommending one debug command from another one sounds fine to me.\n\nAlso documentation about share-safe in `hg help -e share -v` was lacking correct\ndescription on how upgrade existing shares. This fixes that and also start\nmentioning about debugsharesafe.","testPlan":"","lineCount":"24","dependsOn":["9570"],"reviewers":[],"ccs":["mercurial-patches"],"actions":[{"type":"plan-changes","author":"pulkit","id":"146083","dateCreated":"1609935160","dateModified":"1609935160"},{"type":"comment","comment":":white_check_mark: refresh by Heptapod after a successful CI run (:octopus: :green_heart:)","author":"baymax","id":"146081","dateCreated":"1609934020","dateModified":"1609934020"},{"type":"update","diffId":"24611","author":"baymax","id":"146080","dateCreated":"1609934020","dateModified":"1609934020"},{"type":"update","diffId":"24195","author":"pulkit","id":"144155","dateCreated":"1607770008","dateModified":"1607770008"}],"dateCreated":"1607770008","dateModified":"1609935160","status":"Changes Planned"},{"id":"9570","callsign":"HG","title":"debugcommands: introduce command to upgrade\/downgrade shares","author":"pulkit","summary":"In past few months, we have developed functionality to share requirements and\nconfigs of share-source and a way to upgrade repository from old format to\nshare-safe format using `debugupgraderepo` command.\n\nHowever there is still no way to upgrade the shares as `debugupgraderepo` does\nnot support upgrading that.\n\nHaving share-safe rolled out in existing setup is quite important and hence we\nneed a way to upgrade existing shares once share-source upgrades.\n\nThis patch introduces a new debug command `debugsharesafe` which can be used to\nupgrade or downgrade shares.\n\nFunctionality to upgrade shares to use the new method is the last thing left in\nthe whole work.","testPlan":"","lineCount":"136","dependsOn":[],"reviewers":[],"ccs":["marmoute","mercurial-patches"],"actions":[{"type":"plan-changes","author":"pulkit","id":"146082","dateCreated":"1609935145","dateModified":"1609935145"},{"type":"comment","comment":":white_check_mark: refresh by Heptapod after a successful CI run (:octopus: :green_heart:)","author":"baymax","id":"146079","dateCreated":"1609934019","dateModified":"1609934019"},{"type":"update","diffId":"24610","author":"baymax","id":"146078","dateCreated":"1609934019","dateModified":"1609934019"},{"type":"comment","comment":">>! In D9570#145047, @pulkit wrote:\n>>>! In D9570#145046, @marmoute wrote:\n>> should we simply teach `hg debugupgraderepo` to do this type of upgrade on shares? I am not comfortable with adding new updata\/downgradfe command for specific requirements as it would become a jungle quite quickly.\n> \n> `hg debugupgraderepo` does not support upgrading shares. It will require some good amount of work to have `hg debugupgraderepo` support shares and hence I didn't go that way.\n\nDo you think we could we have this as some early branching in debugupgraderepo ?","author":"marmoute","id":"145545","dateCreated":"1608625824","dateModified":"1608625824"},{"type":"comment","comment":">>! In D9570#145046, @marmoute wrote:\n> should we simply teach `hg debugupgraderepo` to do this type of upgrade on shares? I am not comfortable with adding new updata\/downgradfe command for specific requirements as it would become a jungle quite quickly.\n\n`hg debugupgraderepo` does not support upgrading shares. It will require some good amount of work to have `hg debugupgraderepo` support shares and hence I didn't go that way.","author":"pulkit","id":"145047","dateCreated":"1608294250","dateModified":"1608294250"},{"type":"comment","comment":"should we simply teach `hg debugupgraderepo` to do this type of upgrade on shares? I am not comfortable with adding new updata\/downgradfe command for specific requirements as it would become a jungle quite quickly.","author":"marmoute","id":"145046","dateCreated":"1608292808","dateModified":"1608292808"},{"type":"update","diffId":"24194","author":"pulkit","id":"144147","dateCreated":"1607770003","dateModified":"1607770003"}],"dateCreated":"1607770003","dateModified":"1609935145","status":"Changes Planned"},{"id":"6259","callsign":"HG","title":"[POC] revset: on-disk cache for children queries","author":"joerg.sonnenberger","summary":"This is a proof of concept for further discussion.","testPlan":"","lineCount":"175","dependsOn":[],"reviewers":["marmoute","baymax"],"ccs":["pulkit","mercurial-patches","marmoute","martinvonz","indygreg","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"145542","dateCreated":"1608625355","dateModified":"1608625355"},{"type":"reject","author":"baymax","id":"145541","dateCreated":"1608625355","dateModified":"1608625355"},{"type":"comment","comment":"The approach used by the nodemap is probably a good way forward for transactional case. Some kind of happen only index, that get recompacked on a regular basis. Combined with an append only data file (for example, children can be stored as linked list (data file size) with a pointer to the first entry in an index file.","author":"marmoute","id":"134946","dateCreated":"1599812642","dateModified":"1599812642"},{"type":"comment","comment":"Yes, it's still a POC. I wanted to make sure that it works in the modern world, but I am still considering the idea in the context of larger changes for transactional caches.","author":"joerg.sonnenberger","id":"131111","dateCreated":"1595252777","dateModified":"1595252777"},{"type":"comment","comment":"@joerg.sonnenberger Is this still a POC? I see that you updated the code.","author":"pulkit","id":"131101","dateCreated":"1595249913","dateModified":"1595249913"},{"type":"update","diffId":"21871","author":"joerg.sonnenberger","id":"130326","dateCreated":"1594605152","dateModified":"1594605152"},{"type":"comment","comment":"This is POC, so moving out of review.","author":"marmoute","id":"126451","dateCreated":"1587571538","dateModified":"1587571538"},{"type":"reject","author":"marmoute","id":"126450","dateCreated":"1587571538","dateModified":"1587571538"},{"type":"comment","comment":"If we have one, we'll want it to be generic (so also for changelog). Do we have performance number of the time it takes to build it ?","author":"marmoute","id":"117298","dateCreated":"1579799991","dateModified":"1579799991"},{"type":"comment","comment":"Perhaps we'd want this to not be specifically for revsets? We could also write to it when we write to the changelog to keep it up to date.","author":"martinvonz","id":"91118","dateCreated":"1555507748","dateModified":"1555507748"},{"type":"comment","comment":"For the NetBSD repository, a trivial test with the new cache:\n\n```\ntime hg log -r '1000~-400' -T {node} > \/dev\/null\nreal\t0m1.898s\ntime hg log -r '1000~-400' -T {node} > \/dev\/null\nreal\t0m0.170s\ntime hg log -r '1000~-1' -T {node} > \/dev\/null\nreal\t0m0.166s\ntime hg log -r '440000~-1' -T {node} > \/dev\/null\nreal\t0m0.170s\n```\n\nFirst one includes the time to initially warmup the cache.\n\nWithout the cache:\n```\ntime hg log -r '1000~0' -T {node} > \/dev\/null\nreal\t0m0.196s\ntime hg log -r '1000~-1' -T {node} > \/dev\/null\nreal\t0m0.825s\ntime hg log -r '1000~-2' -T {node} > \/dev\/null\nreal\t0m1.288s\ntime hg log -r '1000~-400' -T {node} > \/dev\/null\nreal\t3m23.201s\ntime hg log -r '440000~-1' -T {node} > \/dev\/null\nreal\t0m0.182s\n```\n\nIn other words, building the cache is amortised by one or two queries for children early up in the tree. The cache still provides a good benefit nearer to tip.","author":"joerg.sonnenberger","id":"91110","dateCreated":"1555505679","dateModified":"1555505679"},{"type":"comment","comment":"Do you have performance numbers to share? Substantial wins would definitely pique my interest :)","author":"indygreg","id":"91066","dateCreated":"1555498467","dateModified":"1555498467"},{"type":"update","diffId":"14789","author":"joerg.sonnenberger","id":"91040","dateCreated":"1555454599","dateModified":"1555454599"}],"dateCreated":"1555454599","dateModified":"1608625355","status":"Needs Revision"},{"id":"8972","callsign":"HG","title":"[WIP] diff: add a `--tool` flag","author":"pulkit","summary":"This is a WIP because it's mostly plumbing at the moment and wanted to share it\nwith others.","testPlan":"","lineCount":"189","dependsOn":[],"reviewers":["baymax"],"ccs":["marmoute","mercurial-patches"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"145539","dateCreated":"1608625354","dateModified":"1608625354"},{"type":"reject","author":"baymax","id":"145538","dateCreated":"1608625354","dateModified":"1608625354"},{"type":"comment","comment":"Should we move this to change requested since this is WIP ?","author":"marmoute","id":"134951","dateCreated":"1599812972","dateModified":"1599812972"},{"type":"update","diffId":"22490","author":"pulkit","id":"134314","dateCreated":"1598710710","dateModified":"1598710710"}],"dateCreated":"1598710710","dateModified":"1608625354","status":"Needs Revision"},{"id":"9159","callsign":"HG","title":"[RFC] merge: stop caring about whether files are related (issue6163)","author":"martinvonz","summary":"See discussion in\nhttps:\/\/bz.mercurial-scm.org\/show_bug.cgi?id=6163. D9130 reminded me\nof this idea.","testPlan":"","lineCount":"74","dependsOn":[],"reviewers":["marmoute","pulkit"],"ccs":["pulkit","marmoute","mercurial-patches"],"actions":[{"type":"reject","author":"marmoute","id":"143218","dateCreated":"1607123050","dateModified":"1607123050"},{"type":"comment","comment":">>! In D9159#143135, @martinvonz wrote:\n>>>! In D9159#143133, @pulkit wrote:\n>> IIUC changes are planned on this one as the test case mentioned fails with this patch. Kindly correct me if I am wrong.\n> \n> Yes, I'll see if I can fix that without making things too slow. If I can't, this patch may still be an improvement since it fixes many of the more common cases and breaks a less common one.\n\nPlease note that the changesets centric code (and tests) is still in active development on both is behavior (they are probably more bug laying around) and performance. Please refrain from sending patch in this area without coordinating with the people at Octobus doing that work. Thanks.","author":"marmoute","id":"143217","dateCreated":"1607123030","dateModified":"1607123030"},{"type":"comment","comment":">>! In D9159#143133, @pulkit wrote:\n> IIUC changes are planned on this one as the test case mentioned fails with this patch. Kindly correct me if I am wrong.\n\nYes, I'll see if I can fix that without making things too slow. If I can't, this patch may still be an improvement since it fixes many of the more common cases and breaks a less common one.","author":"martinvonz","id":"143135","dateCreated":"1607108659","dateModified":"1607108659"},{"type":"comment","comment":"IIUC changes are planned on this one as the test case mentioned fails with this patch. Kindly correct me if I am wrong.","author":"pulkit","id":"143133","dateCreated":"1607108461","dateModified":"1607108461"},{"type":"reject","author":"pulkit","id":"143132","dateCreated":"1607108461","dateModified":"1607108461"},{"type":"update","diffId":"23140","author":"martinvonz","id":"137919","dateCreated":"1602229052","dateModified":"1602229052"},{"type":"comment","comment":"test\n\n>>! In D9159#137749, @martinvonz wrote:\n>>>! In D9159#137729, @marmoute wrote:\n>> Regardless of the issue6163 question, simply dropping the tracking or removed files seems wrong and will introduces bug (eg: we can end up merging a \"dead\" file history with a fresh file history, picking the \"dead\" one). So we cannot do that.\n>> \n>> minimal description of the case I am talking about below.\n>> \n>> ```\n>> o \u2192 X should be copied from B, not A\n>> | \\\n>> o | delete X \n>> | |\n>> o | rename A to X\n>> | |\n>> | o rename B to X\n>> |\/\n>> o\n>> ```\n> \n> I added that test as a parent of this patch (D9171). It passed before and after this patch. Did I not write it down correctly?\n\nHmm, I must have run tests on another version of something, because the test now fails for me with this patch, which makes sense. I think I once had a check in the code merging the copy dicts from each merge parent to make it ignore copies that had been deleted (like in this test case), but it was really slow. I took a quick look but I didn't find it and it's getting late here.","author":"martinvonz","id":"137918","dateCreated":"1602228902","dateModified":"1602228902"},{"type":"update","diffId":"23123","author":"martinvonz","id":"137894","dateCreated":"1602224920","dateModified":"1602224920"},{"type":"comment","comment":">>! In D9159#137869, @marmoute wrote:\n> My previous, larger comment got lost. It contained other tests cases.\n> \n> I do not have time re-type my full comment (phabricator eating comment is very upsetting).\n\nWeird, never happened to me.\n\n> Please stop pushing this diff forward, it is broken.\n\nWell, you'll have to provide at least some proof of *what* is broken then.","author":"martinvonz","id":"137870","dateCreated":"1602194479","dateModified":"1602194479"},{"type":"comment","comment":"My previous, larger comment got lost. It contained other tests cases.\n\nI do not have time re-type my full comment (phabricator eating comment is very upsetting). Please stop pushing this diff forward, it is broken.","author":"marmoute","id":"137869","dateCreated":"1602193033","dateModified":"1602193033"},{"type":"reject","author":"marmoute","id":"137868","dateCreated":"1602193033","dateModified":"1602193033"},{"type":"comment","comment":"I've exported the current state so you can see the differences on the entire test suite, but I plan to make it configurable so it can be rolled out slowly. Maybe I'll make a copy of `test-copies-unrelated.t` then, or maybe I'll add another `#testcases follow nofollow` to the file.","author":"martinvonz","id":"137836","dateCreated":"1602178082","dateModified":"1602178082"},{"type":"plan-changes","author":"martinvonz","id":"137835","dateCreated":"1602178082","dateModified":"1602178082"},{"type":"update","diffId":"23113","author":"martinvonz","id":"137831","dateCreated":"1602177832","dateModified":"1602177832"},{"type":"update","diffId":"23111","author":"martinvonz","id":"137822","dateCreated":"1602173916","dateModified":"1602173916"},{"type":"comment","comment":">>! In D9159#137729, @marmoute wrote:\n> Regardless of the issue6163 question, simply dropping the tracking or removed files seems wrong and will introduces bug (eg: we can end up merging a \"dead\" file history with a fresh file history, picking the \"dead\" one). So we cannot do that.\n> \n> minimal description of the case I am talking about below.\n> \n> ```\n> o \u2192 X should be copied from B, not A\n> | \\\n> o | delete X \n> | |\n> o | rename A to X\n> | |\n> | o rename B to X\n> |\/\n> o\n> ```\n\nI added that test as a parent of this patch (D9171). It passed before and after this patch. Did I not write it down correctly?","author":"martinvonz","id":"137749","dateCreated":"1602170117","dateModified":"1602170117"},{"type":"update","diffId":"23082","author":"martinvonz","id":"137744","dateCreated":"1602170063","dateModified":"1602170063"},{"type":"comment","comment":"We would also need more code for simpler case:\n\n```\n4 \u2192 copy tracing from 1 to 4 should not list X\u2190Y \n| \\\n3 | delete Y\n|\/\n2 rename X \u2192 Y\n|\n1 \u2026\n```","author":"marmoute","id":"137731","dateCreated":"1602149158","dateModified":"1602149158"},{"type":"comment","comment":"Regardless of the issue6163 question, simply dropping the tracking or removed files seems wrong and will introduces bug (eg: we can end up merging a \"dead\" file history with a fresh file history, picking the \"dead\" one). So we cannot do that.\n\nminimal description of the case I am talking about below.\n\n```\no \u2192 X should be copied from B, not A\n| \\\no | delete X \n| |\no | rename A to X\n| |\n| o rename B to X\n|\/\no\n```","author":"marmoute","id":"137729","dateCreated":"1602148862","dateModified":"1602148862"},{"type":"reject","author":"marmoute","id":"137728","dateCreated":"1602148862","dateModified":"1602148862"},{"type":"update","diffId":"23064","author":"martinvonz","id":"137583","dateCreated":"1602029150","dateModified":"1602029150"}],"dateCreated":"1602029150","dateModified":"1607123050","status":"Needs Revision"},{"id":"9374","callsign":"HG","title":"bisect: add a `--rev` flag","author":"SimonSapin","summary":"This is the same as the positional argument, and can be passed more than once.","testPlan":"","lineCount":"9","dependsOn":[],"reviewers":["Alphare","martinvonz"],"ccs":["martinvonz","marmoute","mharbison72","mercurial-patches"],"actions":[{"type":"inline","comment":"nit: while you're touching this code, could you also rename this variable to `revs` to make it clear that it's a collection?","replyTo":null,"isNewFile":"1","line":"913","lineLength":"0","path":"mercurial\/commands.py","diffId":"23631","author":"martinvonz","id":"143169","dateCreated":"1607111340","dateModified":"1607111340"},{"type":"inline","comment":"I fear that this will increase the likelihood that the user runs `hg bisect -r abc123`, so could you insert a patch before this one to make sure that that is an error?","replyTo":null,"isNewFile":"1","line":"894","lineLength":"0","path":"mercurial\/commands.py","diffId":"23631","author":"martinvonz","id":"143168","dateCreated":"1607111340","dateModified":"1607111340"},{"type":"reject","author":"martinvonz","id":"143167","dateCreated":"1607111340","dateModified":"1607111340"},{"type":"inline","comment":"The addition of `--rev` is more to mirror other command that take revset as unnamed argument (eg export). I am totally fine with also making multiple revs accepted by this command.","replyTo":"141155","isNewFile":"1","line":"236","lineLength":"0","path":"tests\/test-bisect.t","diffId":"23631","author":"marmoute","id":"141680","dateCreated":"1606497871","dateModified":"1606497871"},{"type":"inline","comment":"I'm curious what other reviewers think from an API design- the good\/bad\/skip is a bool, so it feels strange to get the first revspec free, but then need an option for subsequent ones. Can't multiple revspecs be passed in the way a list of files can be passed into file based commands?\n\nRelated: https:\/\/bz.mercurial-scm.org\/show_bug.cgi?id=5530","replyTo":null,"isNewFile":"1","line":"236","lineLength":"0","path":"tests\/test-bisect.t","diffId":"23631","author":"mharbison72","id":"141155","dateCreated":"1606282713","dateModified":"1606282713"},{"type":"accept","author":"Alphare","id":"141027","dateCreated":"1606216659","dateModified":"1606216659"},{"type":"update","diffId":"23631","author":"SimonSapin","id":"140930","dateCreated":"1606151872","dateModified":"1606151872"}],"dateCreated":"1606151872","dateModified":"1607111340","status":"Needs Revision"},{"id":"7575","callsign":"HG","title":"hg-core: vendor Facebook's configparser crate","author":"indygreg","summary":"I added a number of files from https:\/\/github.com\/facebookexperimental\/eden\nat commit b745b4421b8a8b130d2094b598cedf65655410ec. Files are unmodified from\ntheir original versions. However, the paths are different: I've put all\nfiles in the same directory. And I've removed some files we don't care about\n(such as the C++ bindings and CMake rules). Notably missing is the\nauto-generated parser.rs and the Python script to generate it. We will\nbe able to generate this file automatically at build time (unlike\nFacebook, which is constrained by not using Cargo or something).\n\nThe added files are not part of the hg-core project yet. Things will be\nincorporated in future commits.\n\nI haven't extensively audited the added code for functional correctness\nand compatibility. But I did skim it and it seems to be a highly compatible\nconfig parsing implementation. The most suspect code I found was around\nconfig file path handling. There are references to \"tupperware,\" which\nappears to be a Facebook-specific thing. We will want to clean this up\nat some point...","testPlan":"","lineCount":"2319","dependsOn":["7574"],"reviewers":["baymax"],"ccs":["mercurial-patches","marmoute","pulkit","Alphare","quark","durin42","kevincox","mjpieters","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"130683","dateCreated":"1594830054","dateModified":"1594830054"},{"type":"reject","author":"baymax","id":"130682","dateCreated":"1594830054","dateModified":"1594830054"},{"type":"comment","comment":"@Alphare What's your current opinion on this diff, can you mark it accepted or request change appropriatly ?","author":"marmoute","id":"124050","dateCreated":"1584659140","dateModified":"1584659140"},{"type":"comment","comment":"The C bindings need to be dropped in this patch. Queued the previous patches, many thanks for importing things!","author":"pulkit","id":"115312","dateCreated":"1578933475","dateModified":"1578933475"},{"type":"inline","comment":"+1, I'm not sure what the use case for this would be in core.","replyTo":"111444","isNewFile":"1","line":"1","lineLength":"0","path":"rust\/hg-core\/src\/configparser\/c_api.rs","diffId":"18545","author":"durin42","id":"111896","dateCreated":"1576086289","dateModified":"1576086289"},{"type":"inline","comment":"My bad, it looks like you took care of it in a future patch.","replyTo":"111445","isNewFile":"1","line":"226","lineLength":"0","path":"rust\/hg-core\/src\/configparser\/hg.rs","diffId":"18545","author":"Alphare","id":"111457","dateCreated":"1575896534","dateModified":"1575896534"},{"type":"inline","comment":"`pest` is really cool.","replyTo":null,"isNewFile":"1","line":"63","lineLength":"0","path":"rust\/hg-core\/src\/configparser\/spec.pest","diffId":"18545","author":"Alphare","id":"111449","dateCreated":"1575891512","dateModified":"1575891512"},{"type":"inline","comment":"Is this hack still needed as of `1.34.2`?","replyTo":null,"isNewFile":"1","line":"595","lineLength":"0","path":"rust\/hg-core\/src\/configparser\/hg.rs","diffId":"18545","author":"Alphare","id":"111448","dateCreated":"1575891512","dateModified":"1575891512"},{"type":"inline","comment":"Our current strategy is to assume config files to be in local encoding, not UTF-8. This makes sense from Facebook's perspective, but now as an upstream solution (see previous work on `HgPath`).","replyTo":null,"isNewFile":"1","line":"413","lineLength":"0","path":"rust\/hg-core\/src\/configparser\/hg.rs","diffId":"18545","author":"Alphare","id":"111447","dateCreated":"1575891512","dateModified":"1575891512"},{"type":"inline","comment":"+1","replyTo":"111406","isNewFile":"1","line":"262","lineLength":"1","path":"rust\/hg-core\/src\/configparser\/hg.rs","diffId":"18535","author":"Alphare","id":"111446","dateCreated":"1575891512","dateModified":"1575891512"},{"type":"inline","comment":"This function looks very Facebook specific, I don't think we want to include it at all.","replyTo":null,"isNewFile":"1","line":"226","lineLength":"0","path":"rust\/hg-core\/src\/configparser\/hg.rs","diffId":"18545","author":"Alphare","id":"111445","dateCreated":"1575891512","dateModified":"1575891512"},{"type":"inline","comment":"Do we need bindings to C ? I don't see what the use-case is at this stage of the Rust development.","replyTo":null,"isNewFile":"1","line":"1","lineLength":"0","path":"rust\/hg-core\/src\/configparser\/c_api.rs","diffId":"18545","author":"Alphare","id":"111444","dateCreated":"1575891512","dateModified":"1575891512"},{"type":"update","diffId":"18545","author":"indygreg","id":"111411","dateCreated":"1575774205","dateModified":"1575774205"},{"type":"comment","comment":"Thank you for the feedback, @quark! You enlightened me to a few issues I missed during my very quick perusal.\n\nI agree that doing away with the auto-generated `parser.rs` feels like a better solution. I may revise this series yet again...","author":"indygreg","id":"111408","dateCreated":"1575760222","dateModified":"1575760222"},{"type":"inline","comment":"You might want to revert D13875655 for the directory include feature, which has some test changes.","replyTo":null,"isNewFile":"1","line":"72","lineLength":"0","path":"rust\/hg-core\/src\/configparser\/config.rs","diffId":"18535","author":"quark","id":"111407","dateCreated":"1575760006","dateModified":"1575760006"},{"type":"inline","comment":"You might want to respect `$PAGER`. We ignored it to reduce support burden for mis-configuration. ","replyTo":null,"isNewFile":"1","line":"262","lineLength":"1","path":"rust\/hg-core\/src\/configparser\/hg.rs","diffId":"18535","author":"quark","id":"111406","dateCreated":"1575760006","dateModified":"1575760006"},{"type":"inline","comment":"You might want to remove these lines.","replyTo":null,"isNewFile":"1","line":"141","lineLength":"3","path":"rust\/hg-core\/src\/configparser\/hg.rs","diffId":"18535","author":"quark","id":"111405","dateCreated":"1575760006","dateModified":"1575760006"},{"type":"inline","comment":"You might want to follow this and remove the generated code.","replyTo":null,"isNewFile":"1","line":"103","lineLength":"4","path":"rust\/hg-core\/src\/configparser\/generate_parser.py","diffId":"18535","author":"quark","id":"111404","dateCreated":"1575760006","dateModified":"1575760006"},{"type":"update","diffId":"18535","author":"indygreg","id":"111333","dateCreated":"1575749870","dateModified":"1575749870"}],"dateCreated":"1575749870","dateModified":"1606394587","status":"Needs Revision"},{"id":"9061","callsign":null,"title":"test: add bookmark for 'log' in test-completion","author":"sebhtml","summary":"$ .\/run-tests.py\nrunning 931 tests using 4 parallel processes\n...\nFailed test-contrib-emacs.t: output changed\nFailed test-convert-mtn.t: output changed\nFailed test-https.t: output changed\n# Ran 875 tests, 56 skipped, 3 failed.","testPlan":"","lineCount":"2","dependsOn":["9060"],"reviewers":["pulkit","martinvonz"],"ccs":["martinvonz"],"actions":[{"type":"comment","comment":"D8973 was dropped, so this cannot be queued in its current form","author":"martinvonz","id":"139658","dateCreated":"1604944100","dateModified":"1604944100"},{"type":"reject","author":"martinvonz","id":"139656","dateCreated":"1604944100","dateModified":"1604944100"},{"type":"accept","author":"pulkit","id":"136177","dateCreated":"1600930851","dateModified":"1600930851"},{"type":"update","diffId":"22747","author":"sebhtml","id":"135808","dateCreated":"1600529736","dateModified":"1600529736"}],"dateCreated":"1600529736","dateModified":"1605230124","status":"Needs Revision"},{"id":"9060","callsign":null,"title":"test: test 'hg log' using a bookmark","author":"sebhtml","summary":"","testPlan":"","lineCount":"167","dependsOn":[],"reviewers":["pulkit","martinvonz"],"ccs":["martinvonz"],"actions":[{"type":"comment","comment":"D8973 was dropped, so this cannot be queued in its current form","author":"martinvonz","id":"139652","dateCreated":"1604944085","dateModified":"1604944085"},{"type":"reject","author":"martinvonz","id":"139650","dateCreated":"1604944085","dateModified":"1604944085"},{"type":"accept","author":"pulkit","id":"136175","dateCreated":"1600930814","dateModified":"1600930814"},{"type":"comment","comment":"I also ran all the tests.\n\n# Ran 875 tests, 56 skipped, 4 failed.\n\n**Failed test-completion.t: output changed**\n\n```\n\n- log: follow, follow-first, date, copies, keyword, rev, line-range, removed, only-merges, user, only-branch, branch, prune, patch, git, limit, no-merges, stat, graph, style, template, include, exclude\n+ log: follow, follow-first, date, copies, keyword, rev, line-range, removed, only-merges, user, only-branch, branch, bookmark, prune, patch, git, limit, no-merges, stat, graph, style, template, include, exclude\n\n```\n\nI will fix this.\n\n\n**Failed test-contrib-emacs.t: output changed**\n\n\n```\n- passed 1\/1 hg-test-mode--compilation-mode-support\n+ passed 1\/1 hg-test-mode--compilation-mode-support (0.035108 sec)\n \n- Ran 1 tests, 1 results as expected (*) (glob)\n+ Ran 1 tests, 1 results as expected, 0 unexpected (2020-09-19 13:52:31+0000, 0.035428 sec)\n \n```\n\nThe difference is the added elapsed time. It's unrelated to what I changed.\n\n**Failed test-convert-mtn.t: output changed**\n\n\n```\n+ mtn: warning: ssh_agent: failed to connect to agent: $ENOENT$\n\n```\n\nUnrelated.\n\n\n**Failed test-https.t: output changed**\n\n\n\n```\n $ P=\"$CERTSDIR\" hg --config hostsecurity.ciphers=invalid -R copy-pull id https:\/\/localhost:$HGPORT\/\n- abort: could not set ciphers: No cipher can be selected.\n- (change cipher string (invalid) in config)\n- [255]\n+ 5fed3813f7f5\n```\n\nUnrelated too.","author":"sebhtml","id":"135806","dateCreated":"1600524516","dateModified":"1600524516"},{"type":"comment","comment":"It seems to work as expected:\n\n\n```\n$ .\/run-tests.py test-log-bookmark.t\nrunning 1 tests using 1 parallel processes \n.\n# Ran 1 tests, 0 skipped, 0 failed.\n\n```","author":"sebhtml","id":"135805","dateCreated":"1600521628","dateModified":"1600521628"},{"type":"update","diffId":"22746","author":"sebhtml","id":"135798","dateCreated":"1600521434","dateModified":"1600521434"}],"dateCreated":"1600521434","dateModified":"1605230124","status":"Needs Revision"},{"id":"6987","callsign":"HG","title":"debugstrip: add debugstrip to core","author":"navaneeth.suresh","summary":"Until now, `strip` was bootstrapped as an extension. This patch adds\n`debugstrip` on core. For the users who are still used to `strip`\nextension, we will preserve that name.","testPlan":"","lineCount":"362","dependsOn":[],"reviewers":["durin42","baymax"],"ccs":["pulkit","marmoute","mjpieters","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117501","dateCreated":"1579887099","dateModified":"1579887099"},{"type":"reject","author":"baymax","id":"117500","dateCreated":"1579887099","dateModified":"1579887099"},{"type":"update","diffId":"17120","author":"navaneeth.suresh","id":"103852","dateCreated":"1570917594","dateModified":"1570917594"},{"type":"inline","comment":"the documentation should be left as it is.","replyTo":null,"isNewFile":"1","line":"3","lineLength":"0","path":"hgext\/strip.py","diffId":"16914","author":"pulkit","id":"103145","dateCreated":"1570629357","dateModified":"1570629357"},{"type":"inline","comment":"What is going on here? IT seems like the same code with a different formatting.","replyTo":null,"isNewFile":"1","line":"24","lineLength":"10","path":"hgext\/strip.py","diffId":"16914","author":"marmoute","id":"102942","dateCreated":"1570496789","dateModified":"1570496789"},{"type":"inline","comment":"Why do we need that much code to remain into `hgext\/strip.py`. What I would expect to see is a very small file that only register debugstrip as `strip`.","replyTo":null,"isNewFile":"1","line":"1","lineLength":"46","path":"hgext\/strip.py","diffId":"16914","author":"marmoute","id":"102941","dateCreated":"1570496789","dateModified":"1570496789"},{"type":"comment","comment":"@durin42 Done,","author":"navaneeth.suresh","id":"102681","dateCreated":"1570384371","dateModified":"1570384371"},{"type":"update","diffId":"16914","author":"navaneeth.suresh","id":"102677","dateCreated":"1570384085","dateModified":"1570384085"},{"type":"inline","comment":"One or two is fine, you can leave the majority on the legacy extension flavor. We want some using each so we don't have to add a new test to test one of them.","replyTo":"102399","isNewFile":"1","line":"5646","lineLength":"0","path":"mercurial\/commands.py","diffId":"16856","author":"durin42","id":"102414","dateCreated":"1570309334","dateModified":"1570309334"},{"type":"inline","comment":"i see. do i need to replace `strip` by `debugstrip` on every occurrence in tests? otherwise, i would have to revert the changes in the tests and keep the extension as it is.","replyTo":"102397","isNewFile":"1","line":"5646","lineLength":"0","path":"mercurial\/commands.py","diffId":"16856","author":"navaneeth.suresh","id":"102399","dateCreated":"1570306240","dateModified":"1570306240"},{"type":"inline","comment":"debugstrip please (and put it in debugcommands)\n\nand Gregory points out we need a strip extension that preserves the old `strip` name for users that are used to that","replyTo":null,"isNewFile":"1","line":"5646","lineLength":"0","path":"mercurial\/commands.py","diffId":"16856","author":"durin42","id":"102397","dateCreated":"1570305353","dateModified":"1570305353"},{"type":"reject","author":"durin42","id":"102396","dateCreated":"1570305353","dateModified":"1570305353"},{"type":"update","diffId":"16856","author":"navaneeth.suresh","id":"102389","dateCreated":"1570304463","dateModified":"1570304463"}],"dateCreated":"1570304463","dateModified":"1604880960","status":"Needs Revision"},{"id":"7631","callsign":"HG","title":"absorb: allowing committed changes to be absorbed into their ancestors","author":"rdamazio","summary":"Like before, absorb continues to not touch the working directory, so any\nworking directory changes are preserved, even if the working directory parent\nchanges underneath (for instance, because the current revision was replaced\nwhen changes were absorbed into it).\n\nThis can also be combined with --interactive to absorb just part of a\ncommit into its parents.\n\nThis initial implementation has the shortcoming that it does not do anything\nwith the absorbed commit:\n- With obsmarkers, this means the user still needs to evolve, rebase or prune\n manually\n- Without obsmarkers, the old commits would not be stripped at all because\n their child was not replaced","testPlan":"","lineCount":"684","dependsOn":[],"reviewers":["martinvonz","marmoute"],"ccs":["mjacob","marmoute","mharbison72","martinvonz","pulkit","quark","mercurial-devel"],"actions":[{"type":"comment","comment":">>! In D7631#123321, @mharbison72 wrote:\n>>>! In D7631#123318, @mjacob wrote:\n>> I like the name `--from` for the option. It would also make sense in combination with a possible future `--into` option.\n> \n> The unfortunate thing about `--from` is that it implies a range in `hg fold`, whereas here it seems to be a single(?) commit. It does make a lot of sense within the context of this command though (i.e. taking stuff \/\/from\/\/ this commit). And it took me awhile to get comfortable with the meaning in `hg fold`, so maybe it can be changed to something else there? In any event, I don't want to hold this up over an experimental name, just thinking out loud.\n\nThe `--from` in `hg fold` does not only have a different meaning, it\u2019s also a flag that does not take an argument. The `hg fold` command itself takes revisions as arguments, so people might think they pass a revision to `--from` while they actually pass a revision to `hg fold` (having the same meaning as if it is passed to `-r`). Coincidentally, I was asked for help today from someone misusing the command that way. The `hg rewind` command also takes a `--from` option, this time with an argument. I expect that at least one of it might get changed eventually and I think we should not block this patch on that discussion.\n\nOf course, if someone comes up with a name that doesn\u2019t have these problems and is intuitive, we should use that name.\n\n> I tend to agree with @martinvonz that setting the successor back to the commit it was absorbed into would be confusing, and seems like a way to split the stack into two stacks on that destination, with the corresponding merge conflicts. (Would the new \"`hg evolve` => stabilize all descendants functionality\" even stop at the break? I don't think it would.) I get what you're going for though if you want to track content. But it seems like it would cause non power users a lot of confusion.\n\nI prepared a patch that helps to prevent that the stack gets split: https:\/\/foss.heptapod.net\/mercurial\/evolve\/merge_requests\/126\n\nAs an example:\n\n```\necho a > a; hg add a; hg ci -m a\necho b > b; hg add b; hg ci -m b\necho c > c; hg add c; hg ci -m c\necho a1 > a; echo b1 > b; hg ci -m 'change a and b'\necho d > d; hg add d; hg ci -m d\n```\n\nGraph:\n```\n@ (4) d\n|\no (3) change a and b\n|\no (2) c\n|\no (1) b\n|\no (0) a\n```\n\nFirst, let\u2019s emulate a run of `hg absorb --from 3` that adds markers.\n```\nhg up 3\nhg uncommit --all\nhg up 2 --merge\nhg absorb --apply-changes\nhg prune -r 5 -s '6 + 7' --split\n```\n\nGraph:\n```\n@ (8) c\n|\no (7) b\n|\no (6) a\n\n* (4) d\n|\nx (3) change a and b \u2014 split using prune, uncommit as 6, 7\n|\nx (2) c \u2014 rebased using absorb as 8\n|\nx (1) b \u2014 rewritten using absorb as 7\n|\nx (0) a \u2014 amended using absorb as 6\n```\n\nNow, `hg evolve -r 4` would have the following result without the above patch:\n```\no (9) d\n|\n| @ (8) c\n|\/\no (7) b\n|\no (6) a\n\n```\n\nand with the above patch:\n```\no (9) d\n|\n@ (8) c\n|\no (7) b\n|\no (6) a\n```","author":"mjacob","id":"123546","dateCreated":"1583965232","dateModified":"1583965232"},{"type":"comment","comment":">>! In D7631#123318, @mjacob wrote:\n> I like the name `--from` for the option. It would also make sense in combination with a possible future `--into` option.\n\nThe unfortunate thing about `--from` is that it implies a range in `hg fold`, whereas here it seems to be a single(?) commit. It does make a lot of sense within the context of this command though (i.e. taking stuff \/\/from\/\/ this commit). And it took me awhile to get comfortable with the meaning in `hg fold`, so maybe it can be changed to something else there? In any event, I don't want to hold this up over an experimental name, just thinking out loud.\n\nI tend to agree with @martinvonz that setting the successor back to the commit it was absorbed into would be confusing, and seems like a way to split the stack into two stacks on that destination, with the corresponding merge conflicts. (Would the new \"`hg evolve` => stabilize all descendants functionality\" even stop at the break? I don't think it would.) I get what you're going for though if you want to track content. But it seems like it would cause non power users a lot of confusion.","author":"mharbison72","id":"123321","dateCreated":"1583899488","dateModified":"1583899488"},{"type":"inline","comment":"My preferred option would be to add obsmarkers from the absorbed changeset to the changed changesets. This is what I would usually do if I do a poor man\u2019s version of this functionality: I uncommit the \"source\" changeset, absorb, and prune the \"source\" changeset with the changed changesets as the successor.\n\nIt is true that `hg evolve` is likely to not behave in a useful manner in this case. But as someone who almost always specifies a successor when pruning, I already run into these problems regularly. Fixing that is probably out of scope for this discussion.\n\nI tend to say that adding obsmarkers should be part of this patch, but I\u2019m not very familiar with Mercurial\u2019s preferred workflow for things like this.","replyTo":"120507","isNewFile":"1","line":"993","lineLength":"0","path":"hgext\/absorb.py","diffId":"18728","author":"mjacob","id":"123320","dateCreated":"1583896507","dateModified":"1583896507"},{"type":"inline","comment":"I know that it was named like this before, but the name `targetctx` is quite confusing here, especially considering that the user-facing option will be something like `--from` or `--source`.\n\nCan it be changed, in a separate patch, after there is consensus about how the option should be called?","replyTo":null,"isNewFile":"1","line":"983","lineLength":"0","path":"hgext\/absorb.py","diffId":"19981","author":"mjacob","id":"123319","dateCreated":"1583896507","dateModified":"1583896507"},{"type":"comment","comment":"I like the name `--from` for the option. It would also make sense in combination with a possible future `--into` option.","author":"mjacob","id":"123318","dateCreated":"1583896507","dateModified":"1583896507"},{"type":"comment","comment":">>! In D7631#120777, @marmoute wrote:\n> As explained in this comment https:\/\/phab.mercurial-scm.org\/D8030#120771 I find the idea of usign a changeset in place of the working copy interresting. However, this is a larger big UX change that seems to deserve a wider discussion with more of the community involved. In particular I am not convinced about the `--rev` flag usage.\n> \n> See the linked comment for more details.\n> \n> (Sorry for the delay this will involves, I wish the idea had explicitly surfaced earlier).\n\nThe sprint is not happening and I don't think we should wait for the next sprint (fall?) to move forward with this. Here's a Plan Page I wrote down in response to @marmoute's request D8030: on https:\/\/www.mercurial-scm.org\/wiki\/RevisionAsWDirPlan. The decision we reached was to use the name `--at-rev` on that patch. However, and if I understood correctly, the general sentiment was not that all similar arguments (like the on in this patch) should use that but rather that we should pick a name that sounded for each command. So in the case of this patch, I suppose `--from` is fine? We should mark it EXPERIMENTAL, though.\n","author":"martinvonz","id":"123178","dateCreated":"1583818890","dateModified":"1583818890"},{"type":"comment","comment":"As explained in this comment https:\/\/phab.mercurial-scm.org\/D8030#120771 I find the idea of usign a changeset in place of the working copy interresting. However, this is a larger big UX change that seems to deserve a wider discussion with more of the community involved. In particular I am not convinced about the `--rev` flag usage.\n\nSee the linked comment for more details.\n\n(Sorry for the delay this will involves, I wish the idea had explicitly surfaced earlier).","author":"marmoute","id":"120777","dateCreated":"1581636662","dateModified":"1581636662"},{"type":"reject","author":"marmoute","id":"120775","dateCreated":"1581636662","dateModified":"1581636662"},{"type":"inline","comment":"please revert (sorry about this annoying effect of copy detection)","replyTo":null,"isNewFile":"1","line":"4","lineLength":"3","path":"relnotes\/5.3","diffId":"19981","author":"martinvonz","id":"120508","dateCreated":"1581445540","dateModified":"1581445540"},{"type":"inline","comment":"I think we should at least have a TODO about adding them.\n\nBy the way, without the next patch's auto-evolve feature, I'm not sure we should add such markers. I think they would trick `hg evolve` into moving any descendant commits onto the topmost commit that was absorbed into, but that's probably not what the user wants (they probably want child commits to be moved onto the absorbed commit's parent).","replyTo":"118995","isNewFile":"1","line":"993","lineLength":"0","path":"hgext\/absorb.py","diffId":"18728","author":"martinvonz","id":"120507","dateCreated":"1581445540","dateModified":"1581445540"},{"type":"comment","comment":"Sorry about the delay in responding. Please remember to rebase the series to the latest @ on hg-committed (the release notes are otherwise likely to conflict).","author":"martinvonz","id":"120506","dateCreated":"1581445540","dateModified":"1581445540"},{"type":"reject","author":"martinvonz","id":"120505","dateCreated":"1581445540","dateModified":"1581445540"},{"type":"update","diffId":"19981","author":"rdamazio","id":"119744","dateCreated":"1581045061","dateModified":"1581045061"},{"type":"update","diffId":"19979","author":"rdamazio","id":"119740","dateCreated":"1581044150","dateModified":"1581044150"},{"type":"inline","comment":"See the child commit (D7630), which adds the \"evolve\" operation.\n\nBecause of the invariant about parent phases, checking that the revision being absorbed is not public also ensures that everything it's absorbing into is not public. Is that what you were looking for? If the commit A being absorbed is a draft and its parent is public, then absorb just won't find anywhere to absorb the lines and will leave everything in A.\n\nAbout setting obsmarkers from the absorbed commit into the targets, while that's technically correct, I suspect it'll become a hard-to-navigate mess which adds very little. Do you want me to add that?","replyTo":"115317","isNewFile":"1","line":"993","lineLength":"0","path":"hgext\/absorb.py","diffId":"18728","author":"rdamazio","id":"118995","dateCreated":"1580541031","dateModified":"1580541031"},{"type":"comment","comment":"Sorry for the delay in replying here.","author":"rdamazio","id":"118994","dateCreated":"1580541031","dateModified":"1580541031"},{"type":"update","diffId":"19811","author":"rdamazio","id":"118989","dateCreated":"1580541025","dateModified":"1580541025"},{"type":"inline","comment":"That's true in cmd.exe, but msys doesn't seem to care. (That said, I thought check-code enforced quoting around `^`.)","replyTo":"115318","isNewFile":"1","line":"63","lineLength":"0","path":"tests\/test-absorb-rev.t","diffId":"19048","author":"mharbison72","id":"116260","dateCreated":"1579193370","dateModified":"1579193370"},{"type":"inline","comment":"nit: I think I've heard that `^` needs to be quoted on Windows, so maybe `-s '.^+.'`","replyTo":null,"isNewFile":"1","line":"63","lineLength":"0","path":"tests\/test-absorb-rev.t","diffId":"19048","author":"martinvonz","id":"115318","dateCreated":"1578936681","dateModified":"1578936681"},{"type":"inline","comment":"Maybe I'm also misunderstanding what this patch does in that case. `hg absorb -r A` will not obsolete A? I would think it definitely should do that. Perhaps the successors or the absorbed commit should be all the nodes absorbed into as well as any potential leftovers (which were not absorbed).","replyTo":"115301","isNewFile":"1","line":"993","lineLength":"0","path":"hgext\/absorb.py","diffId":"18728","author":"martinvonz","id":"115317","dateCreated":"1578936681","dateModified":"1578936681"},{"type":"comment","comment":">>! In D7631#112604, @rdamazio wrote:\n>>>! In D7631#112414, @quark wrote:\n>> `--rev` seems ambiguous since there might be different kinds of revisions to specify - target and revisions to edit. Maybe something like `--source`, `--from`, `--target`?\n> \n> Done. Used `--source` to match `rebase`.\n\nSorry I didn't notice until now, but `--source` makes me think it will behave like `hg rebase --source` and absorb from the given commit and all its descendants. I would have preferred `--from` (and maybe a `--into` for choosing which commits to absorb into in the future).","author":"martinvonz","id":"115316","dateCreated":"1578936681","dateModified":"1578936681"},{"type":"inline","comment":"I locally added some `hg log --graph` calls before and after absorb call to understand what happens. It will be nice to add them as it will make things easier for others to understand.","replyTo":null,"isNewFile":"1","line":"72","lineLength":"0","path":"tests\/test-absorb-rev.t","diffId":"19048","author":"pulkit","id":"115302","dateCreated":"1578931522","dateModified":"1578931522"},{"type":"inline","comment":"Sorry, I misunderstood the patch earlier. `rewriteutil.precheck` on target rev is not very helpful as we are not obsolete-ing that in this rev, but we are re-writing it's ancestors. So, if target-rev is a head, and `evolution.alloworphans=False` is set, it will still create orphans.\n\nNot sure what's the best way forward, maybe we should do `rewriteutil.precheck` for the parent instead until we start obsoleting this rev.","replyTo":"113171","isNewFile":"1","line":"993","lineLength":"0","path":"hgext\/absorb.py","diffId":"18728","author":"pulkit","id":"115301","dateCreated":"1578931522","dateModified":"1578931522"},{"type":"inline","comment":"I suspect other places may want something similar (e.g. it'd make sense in `rebase --dest`, so I changed revsingle to add the behavior.","replyTo":"114395","isNewFile":"1","line":"1141","lineLength":"0","path":"hgext\/absorb.py","diffId":"18873","author":"rdamazio","id":"114545","dateCreated":"1578358005","dateModified":"1578358005"},{"type":"comment","comment":">>! In D7631#114393, @mharbison72 wrote:\n>>>! In D7631#112604, @rdamazio wrote:\n>>>>! In D7631#112414, @quark wrote:\n>>> `--rev` seems ambiguous since there might be different kinds of revisions to specify - target and revisions to edit. Maybe something like `--source`, `--from`, `--target`?\n>> \n>> Done. Used `--source` to match `rebase`.\n> \n> Is `--exact` from `hg fold` a better model? I don't feel strongly; I only mention it because `hg rebase -s` will take that revision and its descendants, so it's more like \"stack\" in my mind. I'm not sure how many other commands have `-s` off the top of my head, but @martinvonz \n> mentioned adding that to `hg fix` (probably in IRC), and I think mentioned the word \"stack\" in that context. So I might not be the only one to get slightly tripped up by that.\n\nIMHO no, needing `--exact` is actually confusing to almost every user we've talked to, and they'd instead expect that to be the default behavior, with \"fold up to this commit\" being the one that needs a specific flag.\n\n>> I'm assuming no fundamental objections then? Removing the \"RFC\" part so it gets a proper review then.\n> \n> I like it.\n\nThanks","author":"rdamazio","id":"114544","dateCreated":"1578358005","dateModified":"1578358005"},{"type":"update","diffId":"19048","author":"rdamazio","id":"114541","dateCreated":"1578357966","dateModified":"1578357966"},{"type":"inline","comment":"Should it abort if multiple revisions are given, instead of picking the latest?","replyTo":null,"isNewFile":"1","line":"1141","lineLength":"0","path":"hgext\/absorb.py","diffId":"18873","author":"mharbison72","id":"114395","dateCreated":"1577996461","dateModified":"1577996461"},{"type":"comment","comment":">>! In D7631#112604, @rdamazio wrote:\n>>>! In D7631#112414, @quark wrote:\n>> `--rev` seems ambiguous since there might be different kinds of revisions to specify - target and revisions to edit. Maybe something like `--source`, `--from`, `--target`?\n> \n> Done. Used `--source` to match `rebase`.\n\nIs `--exact` from `hg fold` a better model? I don't feel strongly; I only mention it because `hg rebase -s` will take that revision and its descendants, so it's more like \"stack\" in my mind. I'm not sure how many other commands have `-s` off the top of my head, but @martinvonz \nmentioned adding that to `hg fix` (probably in IRC), and I think mentioned the word \"stack\" in that context. So I might not be the only one to get slightly tripped up by that.\n\n> I'm assuming no fundamental objections then? Removing the \"RFC\" part so it gets a proper review then.\n\nI like it.\n","author":"mharbison72","id":"114394","dateCreated":"1577996461","dateModified":"1577996461"},{"type":"update","diffId":"18873","author":"rdamazio","id":"113351","dateCreated":"1576740998","dateModified":"1576740998"},{"type":"inline","comment":"s\/--rev\/--source","replyTo":null,"isNewFile":"1","line":"5","lineLength":"0","path":"relnotes\/next","diffId":"18843","author":"pulkit","id":"113262","dateCreated":"1576655750","dateModified":"1576655750"},{"type":"inline","comment":"s\/--rev\/--source","replyTo":null,"isNewFile":"1","line":"1113","lineLength":"0","path":"hgext\/absorb.py","diffId":"18843","author":"pulkit","id":"113261","dateCreated":"1576655750","dateModified":"1576655750"},{"type":"update","diffId":"18843","author":"rdamazio","id":"113172","dateCreated":"1576644411","dateModified":"1576644411"},{"type":"inline","comment":"Done. Notice that *technically* the user could do such an absorb while in the middle of a merge, but it sounds like a bad idea and inviting troubles, so I'm letting it also disallow that case. I'll be surprised if anyone even notices.","replyTo":"112977","isNewFile":"1","line":"993","lineLength":"0","path":"hgext\/absorb.py","diffId":"18728","author":"rdamazio","id":"113171","dateCreated":"1576644173","dateModified":"1576644173"},{"type":"comment","comment":"> Can you describe the feature a bit in the commit message. Specific things which I feel are missing:\n\nDone\n\n> Also, it will be nice if you add an entry in releasenotes.\n\nDone\n","author":"rdamazio","id":"113170","dateCreated":"1576644173","dateModified":"1576644173"},{"type":"update","diffId":"18841","author":"rdamazio","id":"113166","dateCreated":"1576644148","dateModified":"1576644148"},{"type":"inline","comment":"need to do more checks here about being public commit etc. `rewriteutil.precheck` should help.","replyTo":null,"isNewFile":"1","line":"993","lineLength":"0","path":"hgext\/absorb.py","diffId":"18728","author":"pulkit","id":"112977","dateCreated":"1576585756","dateModified":"1576585756"},{"type":"inline","comment":"`hg status|diff` should be a better command here.","replyTo":null,"isNewFile":"1","line":"73","lineLength":"0","path":"tests\/test-absorb-rev.t","diffId":"18728","author":"pulkit","id":"112976","dateCreated":"1576585756","dateModified":"1576585756"},{"type":"comment","comment":"Can you describe the feature a bit in the commit message. Specific things which I feel are missing:\n\n* what happens to wdir changes\n* what happens if source is a commit is not a head\n\nI understand them but after reading the tests, so might be worth to add them to description.\n\nAlso, it will be nice if you add an entry in releasenotes.","author":"pulkit","id":"112975","dateCreated":"1576585756","dateModified":"1576585756"},{"type":"update","diffId":"18728","author":"rdamazio","id":"112605","dateCreated":"1576304726","dateModified":"1576304726"},{"type":"comment","comment":">>! In D7631#112414, @quark wrote:\n> `--rev` seems ambiguous since there might be different kinds of revisions to specify - target and revisions to edit. Maybe something like `--source`, `--from`, `--target`?\n\nDone. Used `--source` to match `rebase`.\n\nI'm assuming no fundamental objections then? Removing the \"RFC\" part so it gets a proper review then.\n\n","author":"rdamazio","id":"112604","dateCreated":"1576303338","dateModified":"1576303338"},{"type":"update","diffId":"18726","author":"rdamazio","id":"112598","dateCreated":"1576303328","dateModified":"1576303328"},{"type":"comment","comment":"`--rev` seems ambiguous since there might be different kinds of revisions to specify - target and revisions to edit. Maybe something like `--source`, `--from`, `--target`?","author":"quark","id":"112414","dateCreated":"1576261313","dateModified":"1576261313"},{"type":"update","diffId":"18666","author":"rdamazio","id":"112231","dateCreated":"1576216539","dateModified":"1576216539"}],"dateCreated":"1576216539","dateModified":"1601479022","status":"Needs Revision"},{"id":"8982","callsign":"HG","title":"merge: disable `m2-vs-ma` diff optimization in case of flat manifests","author":"pulkit","summary":"4d504e541d3d1a139f8ebbf8c405291140fd1853 introduced an optimization where in\nsome cases we first diff ancestor and second parent, get the list of files\nchanged between them and then only diff for these files between first parent and\nsecond parent.\n\nHowever as the commit message mentions, this optimization is only helpful when\nrebasing very old commits and using treemanifest. On flat manifests, this\noptimization rather adds a bit of overhead.\n\nThis makes optimization not much useful on flat manifests and can be disabled.\n\nNow, while working on solving criss-cross merge issues where we want to create\nnew filenode for some files in initial merges, this optimization was causing\nissues. Since it's filters file for which diff needs to be performed, the files\nwe are concerned with gets filters out and we don't get to store anything\nrelated to those files.\n\nHence, want to disabling the optimization for flat manifests.\n\nThe tests changes are result of fact that we diff more files now in m1-vs-m2\ncomparison.\n\nSmall note: all these criss cross and new filenode thing I am talking about will\nbe behind a config flag. So nothing invasive yet :)","testPlan":"","lineCount":"47","dependsOn":[],"reviewers":["marmoute"],"ccs":["marmoute","mercurial-patches"],"actions":[{"type":"comment","comment":"I will get back to this later. This is no longer needed for the merge work I am doing.","author":"pulkit","id":"136897","dateCreated":"1601470365","dateModified":"1601470365"},{"type":"plan-changes","author":"pulkit","id":"136896","dateCreated":"1601470365","dateModified":"1601470365"},{"type":"update","diffId":"22668","author":"pulkit","id":"135301","dateCreated":"1600336153","dateModified":"1600336153"},{"type":"comment","comment":"Looks good. Out of curiosity, did you do any performance measurement of this?","author":"marmoute","id":"134987","dateCreated":"1599815158","dateModified":"1599815158"},{"type":"accept","author":"marmoute","id":"134986","dateCreated":"1599815158","dateModified":"1599815158"},{"type":"update","diffId":"22585","author":"pulkit","id":"134792","dateCreated":"1599659068","dateModified":"1599659068"},{"type":"update","diffId":"22546","author":"pulkit","id":"134535","dateCreated":"1599289699","dateModified":"1599289699"}],"dateCreated":"1599289699","dateModified":"1601470365","status":"Changes Planned"},{"id":"8977","callsign":"HG","title":"merge: check for dir rename dest before adding ACTION_KEEP","author":"pulkit","summary":"A previous patch in the series blindly uses `ACTION_KEEP` if the file is not\npresent on both remote and ancestor. This was wrong.\n\nWe tries to detect directory renames and in some graft cases, it can be possible\nthat file is not present on both sides but is created in rename destination of\nother directory which exists on remote. In such cases, we need to merge the\nrename source from remote with rename dest from local.\n\nThis patch makes sure we checks for such rename cases before falling back to\n`ACTION_KEEP`.\n\nAction for rename destination can be added while processing rename destination\nor processing rename source. In some cases, when an optimization only diffing\nfiles changes between m2-vs-ma are in play, either of rename dest or rename\nsource might not be processed.\nHence we need to be extra sure about adding action related to rename\ndestination.\n\nThis issue of missing to check dir rename dest was spotted by a future change\nwhere some tests were failing.","testPlan":"","lineCount":"67","dependsOn":[],"reviewers":["marmoute"],"ccs":["marmoute","mercurial-patches"],"actions":[{"type":"comment","comment":"I have some changes which need to be made to this patch according to Yuya's review on mailing list.","author":"pulkit","id":"135636","dateCreated":"1600434255","dateModified":"1600434255"},{"type":"plan-changes","author":"pulkit","id":"135635","dateCreated":"1600434255","dateModified":"1600434255"},{"type":"update","diffId":"22663","author":"pulkit","id":"135272","dateCreated":"1600336088","dateModified":"1600336088"},{"type":"comment","comment":">>! In D8977#135146, @pulkit wrote:\n>>>! In D8977#135054, @marmoute wrote:\n>> Why don't we get a test change with this ?\n> \n> The test changes are visible after disabling the m2-vs-ma optimization. I just plugged it before to minimize the test changes in that patch which disables the optimization.\n\nCan you mention it in the changeset description ?","author":"marmoute","id":"135147","dateCreated":"1600073677","dateModified":"1600073677"},{"type":"comment","comment":">>! In D8977#135054, @marmoute wrote:\n> Why don't we get a test change with this ?\n\nThe test changes are visible after disabling the m2-vs-ma optimization. I just plugged it before to minimize the test changes in that patch which disables the optimization.","author":"pulkit","id":"135146","dateCreated":"1600072367","dateModified":"1600072367"},{"type":"comment","comment":"Why don't we get a test change with this ?","author":"marmoute","id":"135054","dateCreated":"1599828886","dateModified":"1599828886"},{"type":"reject","author":"marmoute","id":"135053","dateCreated":"1599828886","dateModified":"1599828886"},{"type":"update","diffId":"22514","author":"pulkit","id":"134408","dateCreated":"1599047687","dateModified":"1599047687"}],"dateCreated":"1599047687","dateModified":"1600434255","status":"Changes Planned"},{"id":"8968","callsign":"HG","title":"phabricator: Pass through diffoptions","author":"sfink","summary":"","testPlan":"","lineCount":"24","dependsOn":["8524"],"reviewers":["Alphare","indygreg"],"ccs":["indygreg","Alphare","Kwan","mercurial-patches"],"actions":[{"type":"inline","comment":"Mutable default argument.","replyTo":null,"isNewFile":"1","line":"1082","lineLength":"0","path":"hgext\/phabricator.py","diffId":"22486","author":"indygreg","id":"135499","dateCreated":"1600394981","dateModified":"1600394981"},{"type":"inline","comment":"It's weird to pass an `options` dict\/argument only to use a single key.\n\nPerhaps we should do something like this instead:\n\n```\noptions = dict(options or {})\noptions['git'] = True\n\ndiffopts = mdiff.diffopts(**options)\n```","replyTo":null,"isNewFile":"1","line":"726","lineLength":"0","path":"hgext\/phabricator.py","diffId":"22486","author":"indygreg","id":"135498","dateCreated":"1600394981","dateModified":"1600394981"},{"type":"inline","comment":"`[]` and `{}` or any dynamic value should not be used as an argument default because the initially passed value will be used on subsequent invocations if it isn't passed. See https:\/\/docs.python-guide.org\/writing\/gotchas\/#mutable-default-arguments.\n\nFor this pattern, do something like:\n\n```\ndef func(optional=None):\n optional = optional or {}\n```\n\nor\n\n```\ndef func(optional=None):\n if optional is None:\n optional = {}\n```","replyTo":null,"isNewFile":"1","line":"721","lineLength":"0","path":"hgext\/phabricator.py","diffId":"22486","author":"indygreg","id":"135497","dateCreated":"1600394981","dateModified":"1600394981"},{"type":"reject","author":"indygreg","id":"135496","dateCreated":"1600394981","dateModified":"1600394981"},{"type":"inline","comment":"I know it's not technically part of this change, but making `32767` a \"constant\" with an explanation or at least a good name would be nice.","replyTo":null,"isNewFile":"1","line":"725","lineLength":"0","path":"hgext\/phabricator.py","diffId":"22486","author":"Alphare","id":"134835","dateCreated":"1599725844","dateModified":"1599725844"},{"type":"accept","author":"Alphare","id":"134834","dateCreated":"1599725844","dateModified":"1599725844"},{"type":"comment","comment":"Nothing uses this directly, but it makes it much easier to another extension to call into this code and be able to request different diff options","author":"sfink","id":"134287","dateCreated":"1598648407","dateModified":"1598648407"},{"type":"update","diffId":"22486","author":"sfink","id":"134284","dateCreated":"1598648407","dateModified":"1598648407"}],"dateCreated":"1598648407","dateModified":"1600394981","status":"Needs Revision"},{"id":"7026","callsign":"HG","title":"treemanifest: move out of experimental","author":"pulkit","summary":"In recent sprint, we discussed that treemanifest should be moved out of\nexperimental. The feature has been used inside Google, Facebook in some forms\nand was used inside Yandex too for narrow clones.\n\nThere is an issue with diffing of large treemanifests and to fix that some\nPython code needs to be rewritted in C\/Rust. This I think is not a blocker for\ntaking treemanifest out of experimental.\n\nThis patch renames config `experimental.treemanifest` to `storage.treemanifest`.","testPlan":"","lineCount":"59","dependsOn":[],"reviewers":["durin42","baymax"],"ccs":["mercurial-patches","aayjaychan","marmoute","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117498","dateCreated":"1579887097","dateModified":"1579887097"},{"type":"reject","author":"baymax","id":"117497","dateCreated":"1579887097","dateModified":"1579887097"},{"type":"comment","comment":"That sounds fine","author":"durin42","id":"104286","dateCreated":"1571179604","dateModified":"1571179604"},{"type":"comment","comment":"the storage session is more about small configuration of the storage \nsystem without impact on the repository. The `format` section is more \nappropriate for things that deeply impact the repository format.\n\nSo this should probably at least lives in the `format` as \n`format.use-tree-manifest`.\n\nHowever, this is also the first \"scheme\" change we get. repository using \ntree-manifest will never be able to push to a repository not using it. \nThat make `tree-manifest` different from anything that live in the \n`format` section right now.\n\nSo maybe: `format.manifest-scheme=tree-manifest` ?","author":"marmoute","id":"103128","dateCreated":"1570594672","dateModified":"1570594672"},{"type":"update","diffId":"16976","author":"pulkit","id":"103083","dateCreated":"1570568597","dateModified":"1570568597"}],"dateCreated":"1570568597","dateModified":"1599815758","status":"Needs Revision"},{"id":"8457","callsign":"HG","title":"[RFC] metadataonlyctx: demonstrate an error reusing manifest nodes","author":"mharbison72","summary":"Don't queue this, it's for demo purposes only.\n\nThe structure of the revisions being submitted here is admittedly insane, but I\nstumbled into this trying to test for another issue. Since I don't see anything\nobviously wrong, I'm wondering if fix\/absorb\/etc would have similar issues here.\nI converted the RuntimeError to a message so that the operation completes and\ndoesn't rollback the transaction.","testPlan":"","lineCount":"842","dependsOn":[],"reviewers":["marmoute"],"ccs":["mercurial-patches","marmoute","Kwan","mercurial-devel"],"actions":[{"type":"comment","comment":"Bug filed here: https:\/\/bz.mercurial-scm.org\/show_bug.cgi?id=6305\n\nI wonder if D8989 has any effect on this.","author":"mharbison72","id":"134599","dateCreated":"1599327568","dateModified":"1599327568"},{"type":"comment","comment":"II recommend filling up a bug with a link to this Diff.","author":"marmoute","id":"126505","dateCreated":"1587589350","dateModified":"1587589350"},{"type":"comment","comment":">>! In D8457#126469, @marmoute wrote:\n> For demo purpose only \u2192 getting it out of review. Put it back in review if I am wrong.\n\nCorrect. But I would like eyes on it because I have no clue what the problem is, and it might affect other extensions.","author":"mharbison72","id":"126502","dateCreated":"1587577837","dateModified":"1587577837"},{"type":"comment","comment":"For demo purpose only \u2192 getting it out of review. Put it back in review if I am wrong.","author":"marmoute","id":"126469","dateCreated":"1587572200","dateModified":"1587572200"},{"type":"reject","author":"marmoute","id":"126468","dateCreated":"1587572200","dateModified":"1587572200"},{"type":"update","diffId":"21153","author":"mharbison72","id":"126129","dateCreated":"1587136741","dateModified":"1587136741"}],"dateCreated":"1587136741","dateModified":"1599327568","status":"Needs Revision"},{"id":"8524","callsign":"HG","title":"phabricator: add .arcconfig to help messages and comments (issue6331)","author":"sfink","summary":"Wrapping localrepo's loadhgrc() was not working for me because it is too late to wrap loadhgrc when the extension is loaded.","testPlan":"","lineCount":"19","dependsOn":[],"reviewers":["mharbison72","marmoute"],"ccs":["pulkit","marmoute","Kwan","mercurial-patches"],"actions":[{"type":"comment","comment":">>! In D8524#134327, @mharbison72 wrote:\n>>>! In D8524#134326, @sfink wrote:\n>>>>! In D8524#134322, @mharbison72 wrote:\n>>> The documentation updates look good to me, but there are still some code changes that were probably not intentional, and the commit message probably needs an update.\n>> \n>> I updated the commit message to \"add .arcconfig to help messages and comments\", which seems accurate.\n> \n> I meant this, which is still in the summary section\n> \n> Wrapping localrepo's loadhgrc() was not working for me because it is too late to wrap loadhgrc when the extension is loaded.\n\nI agree that this needs to be changed.\n\nRest looks good to me, will push once commit description is updated.\n> \n>> This is now the only code change (removing the explicit result variable and instead just using cfg to tell whether we updated any configuration.) This seems to better match the intent documented in mercurial\/localrepo.py:\n>>\n>> Returns a bool indicating whether any additional configs were loaded.\n>>\n>> The only difference with the redundant result variable would be if you loaded in a .arcconfig that did not contain either of the two settings looked at here, and in that case it seems like it would be better to return False.\n>>\n>> What do you think?\n> \n> I understand now. Yeah this code is better. Usually we try to split unrelated documentation updates into a separate commit though, so can you `hg split` this (and get rid of the differential url in one of theme)?\n\n","author":"pulkit","id":"134457","dateCreated":"1599064670","dateModified":"1599064670"},{"type":"comment","comment":">>! In D8524#134326, @sfink wrote:\n>>>! In D8524#134322, @mharbison72 wrote:\n>> The documentation updates look good to me, but there are still some code changes that were probably not intentional, and the commit message probably needs an update.\n> \n> I updated the commit message to \"add .arcconfig to help messages and comments\", which seems accurate.\n\nI meant this, which is still in the summary section\n\n Wrapping localrepo's loadhgrc() was not working for me because it is too late to wrap loadhgrc when the extension is loaded.\n\n> This is now the only code change (removing the explicit result variable and instead just using cfg to tell whether we updated any configuration.) This seems to better match the intent documented in mercurial\/localrepo.py:\n>\n> Returns a bool indicating whether any additional configs were loaded.\n>\n> The only difference with the redundant result variable would be if you loaded in a .arcconfig that did not contain either of the two settings looked at here, and in that case it seems like it would be better to return False.\n>\n> What do you think?\n\nI understand now. Yeah this code is better. Usually we try to split unrelated documentation updates into a separate commit though, so can you `hg split` this (and get rid of the differential url in one of theme)?","author":"mharbison72","id":"134327","dateCreated":"1598737569","dateModified":"1598737569"},{"type":"comment","comment":">>! In D8524#134322, @mharbison72 wrote:\n> The documentation updates look good to me, but there are still some code changes that were probably not intentional, and the commit message probably needs an update.\n\nI updated the commit message to \"add .arcconfig to help messages and comments\", which seems accurate.\n\n>> It gets a little messy when uploading partial patches to code that I am patching\n> \n> Are you simply amending your local commit and reposting it with phabsend? If not, I'm not sure what the state of it will be if someone imports it to land it.\n\nSorry, I said that wrong. Yes, I'm doing exactly what you're saying, it's just that the phabsend I'm using is coming from `mozphabricator.py` and I have a whole long stack of patches applied to it, and a corresponding stack of patches applied to `phabricator.py`, and I have to be sure to be in matching places in the stacks or things might get a little mangled (eg adding \"Bug None - Bug None - Bug None -\" to the beginning of the commit message).\n\n>> Ok, the problem I was running into with the exthelper stuff is that it wasn't getting invoked, and it wasn't getting invoked because my extension did not set its uisetup at all. So the fix is very similar to the above: from hgext.phabricator import uisetup\n> \n> I've got a similar extension that wraps the command itself and changes all reviewers to blocking reviewers (so that the first accept doesn't drop it out of everybody else's queue). I don't understand importing `hgext.phabricator.uisetup` though. You should have this somewhere near the top of your extension like `phabricator.py` does\n> \n> eh = exthelper.exthelper()\n> ...\n> uisetup = eh.finaluisetup\n> \n> The underlying machinery simply looks for attributes on the module like `uisetup()`, `reposetup()`, etc, and calls them if present. And yeah, I get confused all the time about the differences between these hooks too.\n\nHm, you may be right. I hadn't needed `exthelper` for anything else in my wrapper yet, so I got rid of it entirely. (I was originally using it, but that meant when I did eg `commands = eh.commands` I wasn't \"inheriting\" the commands from `phabricator.py`. So I switched to `from hgext.phabricator import commands` and then modifying stuff as needed.)\n\nAnyway, whether I do `uisetup = eh.finaluisetup` or `from hgext.phabricator import uisetup` doesn't matter too much; it ends up having the same effect. Given that `phabricator.py` already has an `exthelper` object instantiated with configuration on it that I want to use, it seems a little odd to make another one in my module. Perhaps a midway point would be `from hgext.phabricator import eh` and then `commands = eh.commands` etc.\n","author":"sfink","id":"134326","dateCreated":"1598734153","dateModified":"1598734153"},{"type":"inline","comment":"This is now the only code change (removing the explicit `result` variable and instead just using `cfg` to tell whether we updated any configuration.) This seems to better match the intent documented in `mercurial\/localrepo.py`:\n```\n Returns a bool indicating whether any additional configs were loaded.\n```\nThe only difference with the redundant `result` variable would be if you loaded in a `.arcconfig` that did not contain either of the two settings looked at here, and in that case it seems like it would be better to return `False`.\n\nWhat do you think?\n","replyTo":null,"isNewFile":"1","line":"203","lineLength":"0","path":"hgext\/phabricator.py","diffId":"22485","author":"sfink","id":"134325","dateCreated":"1598733384","dateModified":"1598733384"},{"type":"comment","comment":"The documentation updates look good to me, but there are still some code changes that were probably not intentional, and the commit message probably needs an update.\n\n> It gets a little messy when uploading partial patches to code that I am patching\n\nAre you simply amending your local commit and reposting it with phabsend? If not, I'm not sure what the state of it will be if someone imports it to land it.\n\n> Ok, the problem I was running into with the exthelper stuff is that it wasn't getting invoked, and it wasn't getting invoked because my extension did not set its uisetup at all. So the fix is very similar to the above: from hgext.phabricator import uisetup\n\nI've got a similar extension that wraps the command itself and changes all reviewers to blocking reviewers (so that the first accept doesn't drop it out of everybody else's queue). I don't understand importing `hgext.phabricator.uisetup` though. You should have this somewhere near the top of your extension like `phabricator.py` does\n\n eh = exthelper.exthelper()\n ...\n uisetup = eh.finaluisetup\n\nThe underlying machinery simply looks for attributes on the module like `uisetup()`, `reposetup()`, etc, and calls them if present. And yeah, I get confused all the time about the differences between these hooks too.\n","author":"mharbison72","id":"134322","dateCreated":"1598722113","dateModified":"1598722113"},{"type":"reject","author":"mharbison72","id":"134321","dateCreated":"1598722113","dateModified":"1598722113"},{"type":"comment","comment":"It gets a little messy when uploading partial patches to code that I am patching","author":"sfink","id":"134282","dateCreated":"1598645746","dateModified":"1598645746"},{"type":"update","diffId":"22485","author":"sfink","id":"134281","dateCreated":"1598645746","dateModified":"1598645746"},{"type":"comment","comment":"I thought I would at least keep the help message updates instead of scrapping the whole thing.","author":"sfink","id":"134279","dateCreated":"1598645388","dateModified":"1598645388"},{"type":"update","diffId":"22484","author":"sfink","id":"134276","dateCreated":"1598645388","dateModified":"1598645388"},{"type":"comment","comment":"I finally got around to looking at why I needed this. It turned out to be pretty complicated, and although this patch would work for me, I'm sure there are other ways to work around this so it may not make sense to land.\n\nAt first, I thought it was simple: the wrapped `loadhgrc` is defined in an extension, and knowing what extensions exist requires loading the `.hgrc` config file, so of course it can't possibly work and everybody who is using it successfully must be, uh, liars or something!\n\nBut it appears that this `loadhgrc` is only used for loading a repository's `.hg\/hgrc`, so the above logic is wrong.\n\nOk, here's where it gets weird. What I'm doing is making a \"wrapper\" extension `mozphabricator.py` that works by importing selected stuff from mercurial's in-tree `hgext\/phabricator.py`, and then overriding and monkeypatching what I want to change. The problem is that `phabricator.py` hooks into the repo-specific `.hgrc` loading via `@exthelper.exthelper().wrapfunction(localrepo, \"loadhgrc\")`. When I thought using `loadhgrc` was just completely wrong, the implementation was trivial: just do `from hgext.phabricator import reposetup` and it just works.\n\nAha! Ok, the problem I was running into with the `exthelper` stuff is that it wasn't getting invoked, and it wasn't getting invoked because my extension did not set its `uisetup` at all. So the fix is very similar to the above: `from hgext.phabricator import uisetup`.\n","author":"sfink","id":"134275","dateCreated":"1598638562","dateModified":"1598638562"},{"type":"comment","comment":"There seems to be extra explanation and style change required (as per @mharbisson72 comment).","author":"marmoute","id":"128599","dateCreated":"1591638000","dateModified":"1591638000"},{"type":"reject","author":"marmoute","id":"128598","dateCreated":"1591638000","dateModified":"1591638000"},{"type":"inline","comment":"`if not repo.local()` is the typical way to do this check.","replyTo":null,"isNewFile":"1","line":"175","lineLength":"0","path":"hgext\/phabricator.py","diffId":"21386","author":"mharbison72","id":"127507","dateCreated":"1589648649","dateModified":"1589648649"},{"type":"comment","comment":"I'll try to take a closer look at this some time this weekend. In the meantime, can you explain more why it didn't work for you? There are tests that cover this feature, so I'm wondering if some coverage is missing.\n\nI'm not sure if this is intentional, but it appears that it will unconditionally override even `.hg\/hgrc` configs if `.arcconfig` is present. Before it would only override the global config, load `.arcconfig`, and then load `.hg\/hgrc`. I guess it's only a small benefit that you could re-target the phab instance without dirtying the repo, so I'm not strongly against the change.\n\nOne of the lines looks like it might be long-ish, so you might want to run `.\/run-tests --local test-phabricator.t test-check-*` to make sure it's OK.","author":"mharbison72","id":"127506","dateCreated":"1589648649","dateModified":"1589648649"},{"type":"update","diffId":"21386","author":"sfink","id":"127460","dateCreated":"1589501713","dateModified":"1589501713"}],"dateCreated":"1589501713","dateModified":"1599064670","status":"Needs Revision"},{"id":"6776","callsign":null,"title":"bookmarks: validate changes on push (issue6193) (BC)","author":"idlsoft","summary":"The actual validation is in bundle2.handlebookmark.\nThe rest of the changes are there to pass the force parameter.\nI've also made force available to hooks. That way one can validate who can and cannot use --force on a shared repo.\n\nIn other words, in the case of:\n\n o 2\n | o 1 @\n o\/ 0\n\nwhen I last pulled, @ was on 0, and now I'm doing hg push -B @, but\nsince my last pull the server advanced @ to 2, meaning it's a\nnon-linear update of the bookmark. This used to be allowed, and is now\nprohibited without --force.\n\n.. bc::\n\n `hg push --bookmark` and `hg push -B` no longer move a bookmark\n during push if the new bookmark position isn't a descendant of the\n current bookmark position.\n\n.. feature::\n\n Hooks are now able to tell if --force was specified when a bookmark was pushed.","testPlan":"","lineCount":"203","dependsOn":[],"reviewers":["durin42","baymax"],"ccs":["mjacob","marmoute","pulkit","durin42","valentin.gatienbaron","mercurial-devel"],"actions":[{"type":"comment","comment":"I agree (with some previous answers) that adding more stuff to `--force` should be avoided.\n\nI planned to send a proposal (and patches) after the 5.5 release for adding more detailed options that can be used instead of `--force`. However, due to unexpected reasons, I don\u2019t know whether I\u2019ll have the time for doing that.","author":"mjacob","id":"133095","dateCreated":"1596747653","dateModified":"1596747653"},{"type":"comment","comment":"As I\n\n>>! In D6776#133068, @marmoute wrote:\n> As @valentin.gatienbaron pointed out, the now avoid adding more semantic to bare `--force` with an associated `--force-bookmark` especially because we want to be able to select the bookmarks that get force pushed here.\n\nI've expressed my concerns about that earlier, but ultimately it's a debate for core maintainers, we'll use whatever they decide.\nWithout a clear decision it didn't make much sense to modify the PR.\nI'm not sure if I'll have the bandwith to resume working on this, but glad to see it getting renewed attention.","author":"idlsoft","id":"133069","dateCreated":"1596736255","dateModified":"1596736255"},{"type":"comment","comment":"As @valentin.gatienbaron pointed out, the now avoid adding more semantic to bare `--force` with an associated `--force-bookmark` especially because we want to be able to select the bookmarks that get force pushed here.","author":"marmoute","id":"133068","dateCreated":"1596733563","dateModified":"1596733563"},{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117540","dateCreated":"1579887117","dateModified":"1579887117"},{"type":"reject","author":"baymax","id":"117539","dateCreated":"1579887117","dateModified":"1579887117"},{"type":"comment","comment":"> If you mean \"reject bad pushes as long as people don't push -f\", both versions implement this (the client-side check is not racy thanks to these check:bookmark bundle parts).\nThat was the idea. This implementation is a bit more flexible I think.\nSince it\u2019s server side, you don\u2019t have to upgrade your clients.\nIt\u2019s true old clients won\u2019t be able to use \u2014force, but new ones can.\nAnd you can add a trigger if you want to limit who can use \u2014force.\n\n","author":"idlsoft","id":"100533","dateCreated":"1568441725","dateModified":"1568441725"},{"type":"comment","comment":">>! In D6776#100506, @durin42 wrote:\n>>>! In D6776#100487, @valentin.gatienbaron wrote:\n>> I showed in D6847 the same change but implemented in exchange._processcompared. Tests pass.\n>> I think it'd make for a simpler final state: with the current change, the client sees that the bookmark is going to move sideways, decides this is fine, requests that the server validates that the bookmark is indeed moving sideways (which it does), but in the end the server rejects the move. In the suggested change, the client sees that the bookmark is going sideways and rejects it. This should be consistent with the way new heads or new branches or diverging rewrites are prevented.\n> \n> Isn't that a client-side change only though, so we still need functionality on the server to reject bad pushes? (I could be missing something.)\n\nIf you mean \"reject bad pushes as long as people don't push -f\", both versions implement this (the client-side check is not racy thanks to these check:bookmark bundle parts).\nIf you mean \"reject bad pushes, push -f or not\", a server-side hook is necessary for that, and hook.pretxnclose-bookmark should be able to do the job without any server code change. Server code change can certainly simplify writing such checks, but passing the force parameter on the procol is not needed.","author":"valentin.gatienbaron","id":"100532","dateCreated":"1568440575","dateModified":"1568440575"},{"type":"update","diffId":"16534","author":"idlsoft","id":"100519","dateCreated":"1568436765","dateModified":"1568436765"},{"type":"update","diffId":"16533","author":"idlsoft","id":"100518","dateCreated":"1568428463","dateModified":"1568428463"},{"type":"update","diffId":"16531","author":"idlsoft","id":"100513","dateCreated":"1568420567","dateModified":"1568420567"},{"type":"comment","comment":"> Isn't that a client-side change only though, so we still need functionality on the server to reject bad pushes? (I could be missing something.)\n\nI updated the diff to propagate --force properly","author":"idlsoft","id":"100511","dateCreated":"1568410784","dateModified":"1568420628"},{"type":"comment","comment":">>! In D6776#100487, @valentin.gatienbaron wrote:\n> I showed in D6847 the same change but implemented in exchange._processcompared. Tests pass.\n> I think it'd make for a simpler final state: with the current change, the client sees that the bookmark is going to move sideways, decides this is fine, requests that the server validates that the bookmark is indeed moving sideways (which it does), but in the end the server rejects the move. In the suggested change, the client sees that the bookmark is going sideways and rejects it. This should be consistent with the way new heads or new branches or diverging rewrites are prevented.\n\nIsn't that a client-side change only though, so we still need functionality on the server to reject bad pushes? (I could be missing something.)","author":"durin42","id":"100506","dateCreated":"1568382052","dateModified":"1568382052"},{"type":"comment","comment":"I showed in D6847 the same change but implemented in exchange._processcompared. Tests pass.\nI think it'd make for a simpler final state: with the current change, the client sees that the bookmark is going to move sideways, decides this is fine, requests that the server validates that the bookmark is indeed moving sideways (which it does), but in the end the server rejects the move. In the suggested change, the client sees that the bookmark is going sideways and rejects it. This should be consistent with the way new heads or new branches or diverging rewrites are prevented.\n","author":"valentin.gatienbaron","id":"100487","dateCreated":"1568349208","dateModified":"1568349208"},{"type":"update","diffId":"16524","author":"idlsoft","id":"100462","dateCreated":"1568310366","dateModified":"1568310366"},{"type":"inline","comment":"It will be nice to have documentation about what `force` does in the interface.","replyTo":null,"isNewFile":"1","line":"194","lineLength":"0","path":"mercurial\/interfaces\/repository.py","diffId":"16519","author":"pulkit","id":"100444","dateCreated":"1568268366","dateModified":"1568268366"},{"type":"inline","comment":"Hm, I think `conflicts` can be confusing but I don't have better suggestions here.","replyTo":null,"isNewFile":"1","line":"2149","lineLength":"0","path":"mercurial\/bundle2.py","diffId":"16519","author":"pulkit","id":"100443","dateCreated":"1568268366","dateModified":"1568268366"},{"type":"comment","comment":"I agree with @valentin.gatienbaron that `--force` is quite generic :(. It may create new heads on the server even if I don't want to.","author":"pulkit","id":"100442","dateCreated":"1568268366","dateModified":"1568268366"},{"type":"comment","comment":"We're really close. I've uploaded my rebase of this to the latest dev hg (along with some minor test fixes). There's now only one failure:\n\n```--- \/Users\/augie\/Programming\/hg\/crew\/tests\/test-bookmarks-pushpull.t\n+++ \/Users\/augie\/Programming\/hg\/crew\/tests\/test-bookmarks-pushpull.t#b2-binary.err\n@@ -820,15 +820,17 @@\n pushing to http:\/\/localhost:$HGPORT\/\n searching for changes\n no changes found\n- updating bookmark Z\n- [1]\n+ remote: push rejected: bookmark \"Z\" has changed\n+ remote: (run 'hg pull', resolve conflicts, and push again)\n+ abort: push failed on remote\n+ [255]\n $ hg book -d Z\n $ hg in -B http:\/\/localhost:$HGPORT\/\n comparing with http:\/\/localhost:$HGPORT\/\n searching for changed bookmarks\n @ 9b140be10808\n X 9b140be10808\n- Z 0d2164f0ce0d\n+ Z 9b140be10808\n foo 000000000000\n foobar 9b140be10808\n $ hg pull -B Z http:\/\/localhost:$HGPORT\/\n@@ -853,7 +855,7 @@\n * @ 1:9b140be10808\n X 1:9b140be10808\n Y 4:c922c0139ca0\n- Z 2:0d2164f0ce0d\n+ Z 1:9b140be10808\n foo -1:000000000000\n foobar 1:9b140be10808\n \n\nERROR: test-bookmarks-pushpull.t#b2-binary output changed\n```\n\nMy gut at this point is that we should:\n\n1) Document that legacy bookmark push behavior over pushkey is different\n2) Add a config to reject bookmark pushes over pushkey\n\nBut if there's a way to fix the pushkey behavior too, I'd be interested in that. I'm just not sure it's worth blocking on when that should only matter with very old servers. Obviously if others have stronger opinions they should speak up.","author":"durin42","id":"100418","dateCreated":"1568225245","dateModified":"1568225245"},{"type":"update","diffId":"16519","author":"durin42","id":"100417","dateCreated":"1568225133","dateModified":"1568225133"},{"type":"update","diffId":"16518","author":"idlsoft","id":"100413","dateCreated":"1568217168","dateModified":"1568217168"},{"type":"comment","comment":"I've uploaded my revised version (with the more complete commit message - no other changes) in case that helps.","author":"durin42","id":"100386","dateCreated":"1568212358","dateModified":"1568212358"},{"type":"reject","author":"durin42","id":"100385","dateCreated":"1568212358","dateModified":"1568212358"},{"type":"update","diffId":"16515","author":"durin42","id":"100382","dateCreated":"1568212309","dateModified":"1568212309"},{"type":"comment","comment":"I get a fair number of test failures with this, eg `test-bookmarks-corner-case.t`:\n\n```\n--- \/usr\/local\/google\/home\/augie\/hgtest\/tests\/test-bookmarks-corner-case.t\n+++ \/usr\/local\/google\/home\/augie\/hgtest\/tests\/test-bookmarks-corner-case.t.err\n@@ -178,11 +178,48 @@\n $ hg push -R client-B -r book-B\n pushing to ssh:\/\/user@dummy\/bookrace-server\n searching for changes\n- remote: adding changesets\n- remote: adding manifests\n- remote: adding file changes\n- remote: added 1 changesets with 1 changes to 1 files\n- updating bookmark book-B\n+ ** unknown exception encountered, please report by visiting\n+ ** https:\/\/mercurial-scm.org\/wiki\/BugTracker\n+ ** Python 2.7.16 (default, Apr 6 2019, 01:42:57) [GCC 7.3.0]\n+ ** Mercurial Distributed SCM (version 5.1.1+253-85a0f0de90e5)\n+ ** Extensions loaded:\n+ Traceback (most recent call last):\n+ File \"\/tmp\/hgtests.lYOPXh\/install\/bin\/hg\", line 43, in <module>\n+ dispatch.run()\n+ File \"\/tmp\/hgtests.lYOPXh\/install\/lib\/python\/mercurial\/dispatch.py\", line 99, in run\n+ status = dispatch(req)\n+ File \"\/tmp\/hgtests.lYOPXh\/install\/lib\/python\/mercurial\/dispatch.py\", line 225, in dispatch\n+ ret = _runcatch(req) or 0\n+ File \"\/tmp\/hgtests.lYOPXh\/install\/lib\/python\/mercurial\/dispatch.py\", line 376, in _runcatch\n+ return _callcatch(ui, _runcatchfunc)\n+ File \"\/tmp\/hgtests.lYOPXh\/install\/lib\/python\/mercurial\/dispatch.py\", line 384, in _callcatch\n+ return scmutil.callcatch(ui, func)\n+ File \"\/tmp\/hgtests.lYOPXh\/install\/lib\/python\/mercurial\/scmutil.py\", line 167, in callcatch\n+ return func()\n+ File \"\/tmp\/hgtests.lYOPXh\/install\/lib\/python\/mercurial\/dispatch.py\", line 367, in _runcatchfunc\n+ return _dispatch(req)\n+ File \"\/tmp\/hgtests.lYOPXh\/install\/lib\/python\/mercurial\/dispatch.py\", line 1021, in _dispatch\n+ cmdpats, cmdoptions)\n+ File \"\/tmp\/hgtests.lYOPXh\/install\/lib\/python\/mercurial\/dispatch.py\", line 756, in runcommand\n+ ret = _runcommand(ui, options, cmd, d)\n+ File \"\/tmp\/hgtests.lYOPXh\/install\/lib\/python\/mercurial\/dispatch.py\", line 1030, in _runcommand\n+ return cmdfunc()\n+ File \"\/tmp\/hgtests.lYOPXh\/install\/lib\/python\/mercurial\/dispatch.py\", line 1018, in <lambda>\n+ d = lambda: util.checksignature(func)(ui, *args, **strcmdopt)\n+ File \"\/tmp\/hgtests.lYOPXh\/install\/lib\/python\/mercurial\/util.py\", line 1682, in check\n+ return func(*args, **kwargs)\n+ File \"\/tmp\/hgtests.lYOPXh\/install\/lib\/python\/mercurial\/commands.py\", line 4667, in push\n+ opargs=opargs)\n+ File \"\/tmp\/hgtests.lYOPXh\/install\/lib\/python\/mercurial\/exchange.py\", line 570, in push\n+ _pushbundle2(pushop)\n+ File \"\/tmp\/hgtests.lYOPXh\/install\/lib\/python\/mercurial\/exchange.py\", line 1164, in _pushbundle2\n+ 'force': pushop.force,\n+ File \"\/tmp\/hgtests.lYOPXh\/install\/lib\/python\/mercurial\/thirdparty\/concurrent\/futures\/_base.py\", line 457, in result\n+ return self.__get_result()\n+ File \"\/tmp\/hgtests.lYOPXh\/install\/lib\/python\/mercurial\/wireprotov1peer.py\", line 211, in sendcommands\n+ result = fn(**pycompat.strkwargs(args))\n+ TypeError: unbundle() got an unexpected keyword argument 'force'\n+ [1]\n```\n\nCould I get you to take a look? I like where this is going, but I don't have the time at the moment to hunt down the issues in the tests.","author":"durin42","id":"100381","dateCreated":"1568212284","dateModified":"1568212284"},{"type":"comment","comment":"Queued this with lots of content added to the commit message. Thanks!","author":"durin42","id":"100379","dateCreated":"1568211385","dateModified":"1568211385"},{"type":"accept","author":"durin42","id":"100378","dateCreated":"1568211385","dateModified":"1568211385"},{"type":"comment","comment":"Yes, server changed since your last pull, and you override the bookmark without so much as a warning.","author":"idlsoft","id":"100223","dateCreated":"1568053939","dateModified":"1568053939"},{"type":"comment","comment":"Clarifying I understand: this causes pushing a bookmark to fail in what cases that it currently succeeds? I think it's just the case of:\n\n o 2\n | o 1 @\n o\/ 0\n\nwhen I last pulled, `@` was on 0, and now I'm doing `hg push -B @`, but since my last pull the server advanced `@` to 2, meaning it's a non-linear update. Right?\n\nIf so, I wholeheartedly approve, as this behavior has previously burned me and I think it's well past time we started breaking some compatibility edges on bookmarks to make them actually useful to share.","author":"durin42","id":"100154","dateCreated":"1568043768","dateModified":"1568043768"},{"type":"comment","comment":"I see `--force` as a general \"I know what I'm doing, forget your checks\" instruction.\nIf it's not, then all the variations would need their own `--force-heads`, `--force-bookmarks`, `--force-*`.\nMay be a bit much.\n\nAs for this being configurable?\nI, personally, don't see a lot of value in the current behavior.\nThere may be a use case, but the default behavior, useful for most users, would be to check it, I think.\n","author":"idlsoft","id":"99537","dateCreated":"1567523430","dateModified":"1567523430"},{"type":"comment","comment":"(just interested in this change, I don't have any power to actually accept it)\n\nInteresting. I've thought of `hg push -B` as forcing the move of the bookmark, and `hg push -r` as not forcing a bookmark move, as that's how they behave (well, mostly).\nI don't know if this is a bug: the intended behavior of `push -B` is not explicitly documented, but it at least appears to be consistent with `hg pull -B`.\nBut if it wasn't for compatibility, the behavior you're trying to implement looks superior: it gives the ability to ensure that a push either moves a bookmark forward or fails, which is clearly useful. We have an extension that makes `hg push -r BOOKMARK` have such a behavior, but the fewer extensions the better.\n\nBut given compatibility constraints, this behavior probably needs to be gated by a config option.\n\nAbout more technical aspects, I have a couple of remarks:\n- the change of behavior would be clearer in the diff if you added the test in a first change, and updated the code in a second change\n- the check should probably live in some combination of `exchange.{_processcompared,_pushb2checkbookmarks}` instead (that's where the \"move forward\" logic for push is right now)\n- using `hg push -f` to overwrite the remote bookmark is not great, because -f forces several completely unrelated things (new heads, removes race checks about bookmarks, something about obsolescence markers and something about phases). No one wants to bypass all these at once. Dedicated force flags seems better, perhaps `hg push --force-bookmark BOOKMARK`, to replicate the current behavior of `hg push -B BOOKMARK`.","author":"valentin.gatienbaron","id":"99521","dateCreated":"1567374841","dateModified":"1567374841"},{"type":"comment","comment":"This is a potential fix for https:\/\/bz.mercurial-scm.org\/show_bug.cgi?id=6193\nThe actual validation is in `bundle2.handlebookmark`.\nThe rest of the changes are there to pass the `force` parameter.\nI've also made `force` available to hooks. That way one can validate who can and cannot use `--force` on a shared repo.","author":"idlsoft","id":"99421","dateCreated":"1567188167","dateModified":"1567188167"},{"type":"update","diffId":"16341","author":"idlsoft","id":"99417","dateCreated":"1567187687","dateModified":"1567187687"}],"dateCreated":"1567187687","dateModified":"1596747653","status":"Needs Revision"},{"id":"8347","callsign":"HG","title":"encoding: use special dictionary type for env variables on Windows","author":"indygreg","summary":"Environment variables on Windows are case insensitive and Python\ninternally uses a special dict type that normalizes all keys to\nuppercase.\n\nOur custom bytes-based environment variable dict on Windows was\nnot aware of this, leading to failures when looking up lower case\nenvironment variables (such as `http_proxy`).\n\nThis commit introduces a custom dict type that normalizes keys\nto uppercase on Windows. test-http-proxy.t passes after this\nchange, as a lookup of b'http_proxy' now succeeds.\n\nIt's worth noting that Python's behavior with regards to\nnormalizing all environment variables to uppercase is buggy.\nSee https:\/\/bugs.python.org\/issue28824. I preserved Python's\nbehavior for compatibility.","testPlan":"","lineCount":"36","dependsOn":["8346"],"reviewers":["marmoute","baymax"],"ccs":["mercurial-patches","marmoute","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"132220","dateCreated":"1596218195","dateModified":"1596218195"},{"type":"reject","author":"baymax","id":"132219","dateCreated":"1596218195","dateModified":"1596218195"},{"type":"comment","comment":"Urg, this make me sad, but seems a reasonable way to move forward.","author":"marmoute","id":"126152","dateCreated":"1587148279","dateModified":"1587148279"},{"type":"accept","author":"marmoute","id":"126151","dateCreated":"1587148279","dateModified":"1587148279"},{"type":"update","diffId":"20920","author":"indygreg","id":"124617","dateCreated":"1585531830","dateModified":"1585531830"}],"dateCreated":"1585531830","dateModified":"1596218195","status":"Needs Revision"},{"id":"8345","callsign":"HG","title":"tests: look for CRLF on Windows","author":"indygreg","summary":"The ui.editor code calls util.tonativeeol() to normalize line endings\nto the platform native format. So, editor files may have CRLF\nin them. For some reason, just this one specific test case was\nfailing on Python 3 on Windows. (The output before this change\nwas `...\\r (esc)`, but only on the first line of output. I suspect\nthe test harness output parser was getting confused by the specific\nbyte sequences in this output or something.\n\nI wanted to hack around this by filtering output via sed to remove\nthe CR. But check-code says this practice is apparently banned.\nSo I just made the test conditional.","testPlan":"","lineCount":"23","dependsOn":[],"reviewers":["durin42","marmoute","baymax"],"ccs":["mercurial-patches","marmoute","mharbison72","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"132216","dateCreated":"1596218194","dateModified":"1596218194"},{"type":"reject","author":"baymax","id":"132215","dateCreated":"1596218194","dateModified":"1596218194"},{"type":"accept","author":"marmoute","id":"126180","dateCreated":"1587153646","dateModified":"1587153646"},{"type":"comment","comment":">>! In D8345#126157, @marmoute wrote:\n> @mharbison72 @indygreg, IIRC Matt is saying this is the wrong fix. What's the status of this?\n\nI'm not sure that it's *wrong*, I'm just wondering if there's an encoding and\/or stdio issue lurking here somewhere.","author":"mharbison72","id":"126175","dateCreated":"1587149990","dateModified":"1587149990"},{"type":"comment","comment":"@mharbison72 @indygreg, IIRC Matt is saying this is the wrong fix. What's the status of this?","author":"marmoute","id":"126157","dateCreated":"1587148399","dateModified":"1587148399"},{"type":"comment","comment":"The test harness *should* match existing `\\n` output as a fallback, which got me to wondering if it was the `(esc)` at the end screwing it up. I tried this patch:\n\n```\ndiff --git a\/tests\/run-tests.py b\/tests\/run-tests.py\n--- a\/tests\/run-tests.py\n+++ b\/tests\/run-tests.py\n@@ -2065,6 +2065,8 @@ class TTest(Test):\n if PYTHON3:\n el = el[:-7].decode('unicode_escape') + '\\n'\n el = el.encode('utf-8')\n+ log('el: %s' % el)\n+ log(' l: %s' % l)\n else:\n el = el[:-7].decode('string-escape') + '\\n'\n if el == l or os.name == 'nt' and el[:-1] + b'\\r\\n' == l:\n```\n\n... and got this output:\n\n```\n$ time py -3 run-tests.py --local test-histedit-arguments.t#abortflag --view bcompare\nrunning 1 tests using 1 parallel processes\nel: b'pick 3d3ea1f3a10b 5 1234567890123456789012345678901234567890123456789012345\\xc3\\xa3\\xc2\\x81\\xc2\\x82...\\n'\n l: b'pick 3d3ea1f3a10b 5 1234567890123456789012345678901234567890123456789012345\\xe3\\x81\\x82...\\r\\n'\n```\n\nSo I'm not sure where the bytes are being lost. If this doesn't suggest a larger problem, I've got no problem with this patch as written. But I wonder if there's some stdio that needs to be patched up, because I thought I saw that pattern in some failing py3 tests at one point.","author":"mharbison72","id":"124639","dateCreated":"1585543859","dateModified":"1585543859"},{"type":"update","diffId":"20918","author":"indygreg","id":"124600","dateCreated":"1585531828","dateModified":"1585531828"}],"dateCreated":"1585531828","dateModified":"1596218194","status":"Needs Revision"},{"id":"8346","callsign":"HG","title":"tests: force newlines to LF in tinyproxy.py","author":"indygreg","summary":"Yet another instance where we need to replace the sys.std* streams\nto prevent CRLF from creeping in on Windows.","testPlan":"","lineCount":"18","dependsOn":["8345"],"reviewers":["marmoute","baymax"],"ccs":["mercurial-patches","mharbison72","marmoute","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"132212","dateCreated":"1596218192","dateModified":"1596218192"},{"type":"reject","author":"baymax","id":"132211","dateCreated":"1596218192","dateModified":"1596218192"},{"type":"accept","author":"marmoute","id":"126181","dateCreated":"1587153662","dateModified":"1587153662"},{"type":"comment","comment":"actually @mharbison72 comment on D8345 make me reconsider. Please allign the status of this with the status of D8345.","author":"marmoute","id":"126161","dateCreated":"1587148461","dateModified":"1587148461"},{"type":"resign","author":"marmoute","id":"126158","dateCreated":"1587148461","dateModified":"1587148461"},{"type":"comment","comment":"looks legit","author":"marmoute","id":"126155","dateCreated":"1587148303","dateModified":"1587148303"},{"type":"accept","author":"marmoute","id":"126154","dateCreated":"1587148303","dateModified":"1587148303"},{"type":"update","diffId":"20919","author":"indygreg","id":"124609","dateCreated":"1585531829","dateModified":"1585531829"}],"dateCreated":"1585531829","dateModified":"1596218193","status":"Needs Revision"},{"id":"8348","callsign":"HG","title":"tests: force newlines to LF in inline Python script","author":"indygreg","summary":"Like we've done in what seems like an infinite stream of random\nscripts, we need to set sys.stdout to normalize to LF on\nPython 3 on Windows or else CRLF can creep in.\n\nWith this change, test-fix.t now passes on Python 3 on Windows.","testPlan":"","lineCount":"9","dependsOn":["8347"],"reviewers":["marmoute","baymax"],"ccs":["mercurial-patches","mharbison72","marmoute","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"132208","dateCreated":"1596218191","dateModified":"1596218191"},{"type":"reject","author":"baymax","id":"132207","dateCreated":"1596218191","dateModified":"1596218191"},{"type":"accept","author":"marmoute","id":"126182","dateCreated":"1587153667","dateModified":"1587153667"},{"type":"comment","comment":"actually @mharbison72 comment on D8345 make me reconsider. Please allign the status of this with the status of D8345.","author":"marmoute","id":"126166","dateCreated":"1587148473","dateModified":"1587148473"},{"type":"resign","author":"marmoute","id":"126163","dateCreated":"1587148473","dateModified":"1587148473"},{"type":"comment","comment":"looks legit.","author":"marmoute","id":"126149","dateCreated":"1587148204","dateModified":"1587148204"},{"type":"accept","author":"marmoute","id":"126148","dateCreated":"1587148204","dateModified":"1587148204"},{"type":"update","diffId":"20921","author":"indygreg","id":"124625","dateCreated":"1585531832","dateModified":"1585531832"}],"dateCreated":"1585531832","dateModified":"1596218191","status":"Needs Revision"},{"id":"5496","callsign":"HG","title":"revset: add \"samebranch\" keyword argument to the merge revset","author":"angel.ezquerra","summary":"By default all merges are shown but if \"samebranch\" is set to False then merges\nwith the same branch (i.e. where both parents belong to the same branch) will\nbe filtered out.\n\nConversely, if \"samebranch\" is set to True then only merges with the same branch\nwill be shown.\n\nThis is useful to visualize at a high level the relationships between different\nbranches and how they are merged with each other.\n\nWith the addition of the merge(withbranch) idiom on a previous revision this\ncould already be done in a quite complicated way, by doing something like:\n\nmerge() and branch(somebranch) and not merge(somebranch)\n\nThis is not very practical ano only works for a single branch. Thus this new\noption is added.","testPlan":"","lineCount":"59","dependsOn":["5495"],"reviewers":["baymax"],"ccs":["mercurial-patches","marmoute","mharbison72","yuja","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"132205","dateCreated":"1596218190","dateModified":"1596218190"},{"type":"reject","author":"baymax","id":"132204","dateCreated":"1596218190","dateModified":"1596218190"},{"type":"comment","comment":"Gentle ping on this series, the feature sounds interesting.","author":"marmoute","id":"126445","dateCreated":"1587571245","dateModified":"1587571287"},{"type":"comment","comment":"Maybe we should not try to use boolean. we could have\n\n`merge(parentbranches=\"same\")`\n\nwith the possible value being: `same`, `different`, `any` (an possibly some constains about `branch(p1(x)) == branch(x)`","author":"marmoute","id":"117278","dateCreated":"1579799198","dateModified":"1579799198"},{"type":"comment","comment":"> Maybe `anonymous`, defaulting to True?\n\nTo all: the default can't be True. It would break the current `merge()`\nrevset behavior. Only viable choice is to set the default to \"don't care\".\n\nAnd I think tri-state bool is confusing in this context. So, IMHO, it's\nbetter to add an argument taking a keyword string specifying constraint\nsuch as `merge(between=\"a-keyword-to-select-merges-of-named-branches\")`.\n\n> That's in the glossary under `Branch, anonymous`, so not technically\n> a merge, but I think it still conveys the point.\n\nI disagree. Merges of the same branch are pretty common if your team preferred\nmerge-based strategy. I wouldn't explicitly call new head pulled from public\nrepo as an anonymous head.\n\nIt can also be wrong if you're using bookmarks.","author":"yuja","id":"83416","dateCreated":"1548247882","dateModified":"1548247882"},{"type":"comment","comment":">>! In D5496#82908, @angel.ezquerra wrote:\n>>>! In D5496#82671, @yuja wrote:\n> \n> Do you mean that the flag should only indicate whether you want to hide the same branch merges? I guess that is OK too, since the main use case for this flag is to hide the merge from the same branch. However I think we should change the flag name then. Perhaps \"hidesame\"? Or \"includesame\" or \"includeself\", defaulting to True? Any ideas?\n\nMaybe `anonymous`, defaulting to True? That's in the glossary under `Branch, anonymous`, so not technically a merge, but I think it still conveys the point.\n\nI think I have a similar reaction as Yuya, but in the opposite direction- `merge(anonymous=True)` makes me think that's all that's of interest. So maybe `withanonymous`?\n\nI do like the compactness of:\n\n merge() => all merges\n merge(anonymous=True) => only merges with matching (p1, p2) branch names\n merge(anonymous=False) => only merges with different (p1, p2) branch names\n\nOtherwise finding only anonymous merges is something like `merge() - merge(anonymous=False)`, and it took some thinking to get there with the double negative.\n\nBut I have no idea how well that applies to other things if we set that precedent here, and don't feel that strongly about it.","author":"mharbison72","id":"83200","dateCreated":"1548181703","dateModified":"1548181703"},{"type":"comment","comment":"> > Okay, I didn't notice that. And it's tricky to map `samebranch=False` to\n> > \"different branch\" constraint. I would read it as \"I don't care whether\n> > the branches are the same or not.\"\n> >\n> > We can instead express it as `merge() - merge(samebranch=True)`.\n> \n> Do you mean that the flag should only indicate whether you want to hide the same branch merges?\n\nI just mean tri-state bool is confusing. `<whatever>=False` sounds like we\ndon't care about the `<whatever>` condition.\n\n> I guess that is OK too, since the main use case for this flag is to hide the merge from the same branch. However I think we should change the flag name then. Perhaps \"hidesame\"? Or \"includesame\" or \"includeself\", defaulting to True? Any ideas?\n\nIt could be an argument taking a string like `'same'`, but I can't think\nof nice names. What's the best term describing a merge between two named\nbranches?","author":"yuja","id":"83052","dateCreated":"1547734900","dateModified":"1547734900"},{"type":"comment","comment":">>! In D5496#82671, @yuja wrote:\n>> > `[, samebranch]` or [, samebranch=False]`.\n>> \n>> I guess that means:\n>> \n>> @predicate('merge([withbranch [, samebranch=None]])', safe=True)\n>> \n>> Right? (I realized that it is incorrect to say that samebranch's default value is False).\n> \n> Okay, I didn't notice that. And it's tricky to map `samebranch=False` to\n> \"different branch\" constraint. I would read it as \"I don't care whether\n> the branches are the same or not.\"\n\n>>! In D5496#82671, @yuja wrote:\n>> > `[, samebranch]` or [, samebranch=False]`.\n>> \n>> I guess that means:\n>> \n>> @predicate('merge([withbranch [, samebranch=None]])', safe=True)\n>> \n>> Right? (I realized that it is incorrect to say that samebranch's default value is False).\n> \n> Okay, I didn't notice that. And it's tricky to map `samebranch=False` to\n> \"different branch\" constraint. I would read it as \"I don't care whether\n> the branches are the same or not.\"\n> \n> We can instead express it as `merge() - merge(samebranch=True)`.\n\nDo you mean that the flag should only indicate whether you want to hide the same branch merges? I guess that is OK too, since the main use case for this flag is to hide the merge from the same branch. However I think we should change the flag name then. Perhaps \"hidesame\"? Or \"includesame\" or \"includeself\", defaulting to True? Any ideas?\n","author":"angel.ezquerra","id":"82908","dateCreated":"1547662268","dateModified":"1547662268"},{"type":"comment","comment":"> > `[, samebranch]` or [, samebranch=False]`.\n> \n> I guess that means:\n> \n> @predicate('merge([withbranch [, samebranch=None]])', safe=True)\n> \n> Right? (I realized that it is incorrect to say that samebranch's default value is False).\n\nOkay, I didn't notice that. And it's tricky to map `samebranch=False` to\n\"different branch\" constraint. I would read it as \"I don't care whether\nthe branches are the same or not.\"\n\nWe can instead express it as `merge() - merge(samebranch=True)`.\n\n> > if len(matchfns) == 1:\n> > # fast path for common case\n> > return subset.filter(matchfn[0], ...)\n> > else:\n> > return subset.filter(lambda r: all(p(r) for p in matchfn), ...)\n> \n> Do you think this makes the code simpler?\n\nYes. The original version was hard to find all possible call paths.\nSeparate function per constraint is easier to follow.\n\n> In any case, if you think this approach is best I can do it, but perhaps it would be a little better to keep a single subset.filter call as follows:\n> \n> if len(matchfns) == 1:\n> finalmatchfn = matchfns[0]\n> else:\n> finalmatchfn = lambda r: all(p(r) for p in matchfns)\n> return subset.filter(finalmatchfn, condrepr='<merge>')\n\nI don't care about these differences.","author":"yuja","id":"82671","dateCreated":"1547644201","dateModified":"1547644201"},{"type":"comment","comment":">>! In D5496#82394, @yuja wrote:\n>> -@predicate('merge(withbranch)', safe=True)\n>> +@predicate('merge(withbranch, samebranch=True)', safe=True)\n> \n> `[, samebranch]` or [, samebranch=False]`.\n\nI guess that means:\n\n@predicate('merge([withbranch [, samebranch=None]])', safe=True)\n\nRight? (I realized that it is incorrect to say that samebranch's default value is False).\n\n>> withbranch = ''\n>> if 'withbranch' in args:\n>> withbranch = getstring(args['withbranch'],\n>> _('withbranch argument must be a string'))\n>> kind, branchname, branchmatcher = stringutil.stringmatcher(withbranch)\n>> + samebranch = None\n>> + if 'samebranch' in args:\n>> + # i18n: \"samebranch\" is a keyword\n>> + samebranch = getboolean(args['samebranch'],\n>> + _('samebranch argument must be a True or False'))\n>> cl = repo.changelog\n>> # create the function that will be used to filter the subset\n>> if withbranch:\n>> # matchfn is a function that returns true when a revision\n>> # is a merge and the second parent belongs to a branch that\n>> # matches the withbranch pattern (which can be a literal or a regex)\n>> if kind == 'literal':\n>> - matchfn = lambda r: (cl.parentrevs(r)[1] != -1\n>> - and repo[r].p2().branch() == withbranch)\n>> + basematchfn = lambda r: (cl.parentrevs(r)[1] != -1\n>> + and repo[r].p2().branch() == withbranch)\n>> else:\n>> - matchfn = lambda r: (cl.parentrevs(r)[1] != -1\n>> - and branchmatcher(repo[r].p2().branch()))\n>> - else:\n>> - # matchfn is a function that returns true when a revision is a merge\n>> - matchfn = lambda r: cl.parentrevs(r)[1] != -1\n>> + basematchfn = lambda r: (cl.parentrevs(r)[1] != -1\n>> + and branchmatcher(repo[r].p2().branch()))\n>> + else:\n>> + basematchfn = lambda r: cl.parentrevs(r)[1] != -1\n>> + if samebranch is None:\n>> + matchfn = basematchfn\n>> + else:\n>> + # if samebranch was specified, build a new match function\n>> + # that on top of basematch checks if the parents belong (or not)\n>> + # to the same branch (depending on the value of samebranch)\n>> + def matchfn(r):\n>> + c = repo[r]\n>> + if not basematchfn(r):\n>> + return False\n>> + issamebranchmerge = c.p1().branch() == c.p2().branch()\n>> + return issamebranchmerge if samebranch else not issamebranchmerge\n> \n> These conditions can be formed as followed:\n> \n> ```\n> matchfns = [lambda r: cl.parentrevs(r)[1] != -1]\n> if withbranch:\n> matchfns.append(lambda r: branchmatcher(repo[r].p2().branch()))\n> if samebranch:\n> matchfns.append(samebranchmatchfn)\n> \n> if len(matchfns) == 1:\n> # fast path for common case\n> return subset.filter(matchfn[0], ...)\n> else:\n> return subset.filter(lambda r: all(p(r) for p in matchfn), ...)\n> ```\n\nDo you think this makes the code simpler? In any case, if you think this approach is best I can do it, but perhaps it would be a little better to keep a single subset.filter call as follows:\n\n```\nif len(matchfns) == 1:\n finalmatchfn = matchfns[0]\nelse:\n finalmatchfn = lambda r: all(p(r) for p in matchfns)\nreturn subset.filter(finalmatchfn, condrepr='<merge>')\n```\n\nWhat do you think?\n","author":"angel.ezquerra","id":"82562","dateCreated":"1547596927","dateModified":"1547596927"},{"type":"update","diffId":"13211","author":"angel.ezquerra","id":"82415","dateCreated":"1547508409","dateModified":"1547508409"},{"type":"comment","comment":"> -@predicate('merge(withbranch)', safe=True)\n> +@predicate('merge(withbranch, samebranch=True)', safe=True)\n\n`[, samebranch]` or [, samebranch=False]`.\n\n> withbranch = ''\n> if 'withbranch' in args:\n> withbranch = getstring(args['withbranch'],\n> _('withbranch argument must be a string'))\n> kind, branchname, branchmatcher = stringutil.stringmatcher(withbranch)\n> + samebranch = None\n> + if 'samebranch' in args:\n> + # i18n: \"samebranch\" is a keyword\n> + samebranch = getboolean(args['samebranch'],\n> + _('samebranch argument must be a True or False'))\n> cl = repo.changelog\n> # create the function that will be used to filter the subset\n> if withbranch:\n> # matchfn is a function that returns true when a revision\n> # is a merge and the second parent belongs to a branch that\n> # matches the withbranch pattern (which can be a literal or a regex)\n> if kind == 'literal':\n> - matchfn = lambda r: (cl.parentrevs(r)[1] != -1\n> - and repo[r].p2().branch() == withbranch)\n> + basematchfn = lambda r: (cl.parentrevs(r)[1] != -1\n> + and repo[r].p2().branch() == withbranch)\n> else:\n> - matchfn = lambda r: (cl.parentrevs(r)[1] != -1\n> - and branchmatcher(repo[r].p2().branch()))\n> - else:\n> - # matchfn is a function that returns true when a revision is a merge\n> - matchfn = lambda r: cl.parentrevs(r)[1] != -1\n> + basematchfn = lambda r: (cl.parentrevs(r)[1] != -1\n> + and branchmatcher(repo[r].p2().branch()))\n> + else:\n> + basematchfn = lambda r: cl.parentrevs(r)[1] != -1\n> + if samebranch is None:\n> + matchfn = basematchfn\n> + else:\n> + # if samebranch was specified, build a new match function\n> + # that on top of basematch checks if the parents belong (or not)\n> + # to the same branch (depending on the value of samebranch)\n> + def matchfn(r):\n> + c = repo[r]\n> + if not basematchfn(r):\n> + return False\n> + issamebranchmerge = c.p1().branch() == c.p2().branch()\n> + return issamebranchmerge if samebranch else not issamebranchmerge\n\nThese conditions can be formed as followed:\n\n```\nmatchfns = [lambda r: cl.parentrevs(r)[1] != -1]\nif withbranch:\n matchfns.append(lambda r: branchmatcher(repo[r].p2().branch()))\nif samebranch:\n matchfns.append(samebranchmatchfn)\n\nif len(matchfns) == 1:\n # fast path for common case\n return subset.filter(matchfn[0], ...)\nelse:\n return subset.filter(lambda r: all(p(r) for p in matchfn), ...)\n```","author":"yuja","id":"82395","dateCreated":"1547435478","dateModified":"1547435478"},{"type":"update","diffId":"13205","author":"angel.ezquerra","id":"82389","dateCreated":"1547419525","dateModified":"1547419525"},{"type":"update","diffId":"13018","author":"angel.ezquerra","id":"81361","dateCreated":"1546801412","dateModified":"1546801412"}],"dateCreated":"1546801412","dateModified":"1596218190","status":"Needs Revision"},{"id":"6312","callsign":"HG","title":"branchcache: update the filteredhash if we update the tiprev","author":"pulkit","summary":"We update the tiprev and in next if statement we check whether the branchcache\nis valid or not. If the update of tiprev happens, then definitely\nself.validfor() will return False because filteredhash is old now.\n\nLet's update the filteredhash if we update the tiprev also. This prevents us\nfrom entering the loop where we iter all the heads, and find the tiprev.","testPlan":"","lineCount":"1","dependsOn":[],"reviewers":["baymax"],"ccs":["mercurial-patches","marmoute","yuja","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"132202","dateCreated":"1596218189","dateModified":"1596218189"},{"type":"reject","author":"baymax","id":"132201","dateCreated":"1596218189","dateModified":"1596218189"},{"type":"comment","comment":"reping","author":"marmoute","id":"126454","dateCreated":"1587571582","dateModified":"1587571582"},{"type":"comment","comment":"This seems useful but lingering. @pulkit what's the status of this.","author":"marmoute","id":"117300","dateCreated":"1579800073","dateModified":"1579800073"},{"type":"comment","comment":"> if ntiprev > self.tiprev:\n> self.tiprev = ntiprev\n> self.tipnode = cl.node(ntiprev)\n> + self.filteredhash = scmutil.filteredhash(repo, self.tiprev)\n> \n> if not self.validfor(repo):\n> # cache key are not valid anymore\n\nand update `self.filteredhash` later again, which smells. Instead, shouldn't\nwe check the validity first, and take the fast path only if it was valid?\n\n```\nif self.validfor(repo): # was valid, can take fast path\n self.tiprev = ntiprev\n self.tipnode = cl.node(ntiprev)\nelse: # bad luck, recompute tiprev\/tipnode\n ...\nself.filteredhash = scmutil.filteredhash(repo, self.tiprev)\n```","author":"yuja","id":"91967","dateCreated":"1556440717","dateModified":"1556440717"},{"type":"update","diffId":"14927","author":"pulkit","id":"91837","dateCreated":"1556320974","dateModified":"1556320974"}],"dateCreated":"1556320974","dateModified":"1596218189","status":"Needs Revision"},{"id":"8646","callsign":"HG","title":"update: suggest --merge while `hg up` across topo branches","author":"khanchi97","summary":"Before this patch, during `hg up` across topological branches with\ndirty working directory we suggested the user to \"commit or update\n--clean to discard\"\n\nI think suggesting --merge is better than --clean (which discard\nchanges with no backup). We can keep all the three options, but\nprobably then we will have sacrifice length of message.","testPlan":"","lineCount":"18","dependsOn":[],"reviewers":[],"ccs":["marmoute","mjacob","martinvonz","mercurial-patches"],"actions":[{"type":"plan-changes","author":"khanchi97","id":"130915","dateCreated":"1594924854","dateModified":"1594924854"},{"type":"comment","comment":"also: can we move this to \"change planned\" so that it stop showing up in yadda?","author":"marmoute","id":"130693","dateCreated":"1594830668","dateModified":"1594830668"},{"type":"comment","comment":">>! In D8646#129257, @mjacob wrote:\n> I think it would be a good idea to mention both `--clean` and `--merge`, but mentioning only `--merge` is better than mentioning only `--clean`.\n\n+1 on that.\n\nI hope we can get this soon. ","author":"marmoute","id":"130692","dateCreated":"1594830589","dateModified":"1594830589"},{"type":"comment","comment":"I think it would be a good idea to mention both `--clean` and `--merge`, but mentioning only `--merge` is better than mentioning only `--clean`.","author":"mjacob","id":"129257","dateCreated":"1592917202","dateModified":"1592917202"},{"type":"comment","comment":">>! In D8646#129176, @martinvonz wrote:\n> We have not made this change before because there is no `hg update --abort`. Do we have that feature yet (I haven't followed all the changes recently)?\n\nAh, okay. I see. No, we don't have that feature yet. I sent a patch for `hg update --abort` but I got stuck in a subrepo case where we can lose some changes. I think now I am gonna revisit that case again, and try to figure out the fix or will start a discussion on that. Thanks :)\n(both of these have some discussion on it https:\/\/phab.mercurial-scm.org\/D7786 https:\/\/phab.mercurial-scm.org\/D6735)","author":"khanchi97","id":"129178","dateCreated":"1592806928","dateModified":"1592806928"},{"type":"comment","comment":"We have not made this change before because there is no `hg update --abort`. Do we have that feature yet (I haven't followed all the changes recently)?","author":"martinvonz","id":"129176","dateCreated":"1592802286","dateModified":"1592802286"},{"type":"update","diffId":"21674","author":"khanchi97","id":"129170","dateCreated":"1592791949","dateModified":"1592791949"}],"dateCreated":"1592791949","dateModified":"1594924854","status":"Changes Planned"},{"id":"8616","callsign":"HG","title":"merge: chain copies with existing copies in working copy","author":"martinvonz","summary":"This makes the merge code chain and filter copies when grafting with\ncopies already in the working copy. For example, if the working copy\nhas renamed file A to B and you somehow graft in a change that renames\nB to C, then that will now become a rename from A to C. That will\nsoon be necessary for `hg rebase --collapse`. It seems that we don't\nhave any existing cases where chaining makes a difference.","testPlan":"","lineCount":"16","dependsOn":["8595"],"reviewers":[],"ccs":["marmoute","mercurial-patches"],"actions":[{"type":"inline","comment":"Ah, I see. See `copies.filter()` (called `copies._filter()` at head) for details.","replyTo":"130830","isNewFile":"1","line":"1916","lineLength":"5","path":"mercurial\/merge.py","diffId":"21564","author":"martinvonz","id":"130852","dateCreated":"1594913281","dateModified":"1594913281"},{"type":"comment","comment":"Changes planned to earlier patch in the series","author":"martinvonz","id":"130840","dateCreated":"1594913028","dateModified":"1594913028"},{"type":"plan-changes","author":"martinvonz","id":"130839","dateCreated":"1594913028","dateModified":"1594913028"},{"type":"inline","comment":"Previously, theses extra `ifs` clause were not necessary, Now they appears. Why do they become necessary now ?","replyTo":"130688","isNewFile":"1","line":"1916","lineLength":"5","path":"mercurial\/merge.py","diffId":"21564","author":"marmoute","id":"130830","dateCreated":"1594910013","dateModified":"1594910013"},{"type":"inline","comment":"I guess I don't understand what your question was in that case. Can you rephrase it?","replyTo":"130677","isNewFile":"1","line":"1916","lineLength":"5","path":"mercurial\/merge.py","diffId":"21564","author":"martinvonz","id":"130688","dateCreated":"1594830155","dateModified":"1594830155"},{"type":"inline","comment":"I don't understand how it answser my question of \"why does these new cases pops up?\"","replyTo":"128874","isNewFile":"1","line":"1916","lineLength":"5","path":"mercurial\/merge.py","diffId":"21564","author":"marmoute","id":"130677","dateCreated":"1594829934","dateModified":"1594829934"},{"type":"comment","comment":"(I have an unsubmitted question laying around for over a month\u2026)","author":"marmoute","id":"130676","dateCreated":"1594829934","dateModified":"1594829934"},{"type":"update","diffId":"21608","author":"martinvonz","id":"128876","dateCreated":"1591886052","dateModified":"1591886052"},{"type":"inline","comment":"Did you miss the comment I added on line 1914 or do you think it's not enough? Each case is documented there.","replyTo":"128870","isNewFile":"1","line":"1916","lineLength":"5","path":"mercurial\/merge.py","diffId":"21564","author":"martinvonz","id":"128874","dateCreated":"1591883475","dateModified":"1591883475"},{"type":"inline","comment":"I am not sure why we gain all these new cases? where do they comes from?","replyTo":null,"isNewFile":"1","line":"1916","lineLength":"5","path":"mercurial\/merge.py","diffId":"21564","author":"marmoute","id":"128870","dateCreated":"1591883145","dateModified":"1591883145"},{"type":"update","diffId":"21605","author":"martinvonz","id":"128857","dateCreated":"1591811649","dateModified":"1591811649"},{"type":"comment","comment":">>! In D8616#128712, @marmoute wrote:\n> This patch seems related to D8596 which @martinvonz pointed as \"not meant to be merged\". What should we do with this diff ? is it intended for landing ? If not could get we it out of need-review and marke it RFC ?\n\nThat was on an earlier version of the series; this series is now ready.","author":"martinvonz","id":"128752","dateCreated":"1591711917","dateModified":"1591711917"},{"type":"comment","comment":"This patch seems related to D8596 which @martinvonz pointed as \"not meant to be merged\". What should we do with this diff ? is it intended for landing ? If not could get we it out of need-review and marke it RFC ?","author":"marmoute","id":"128712","dateCreated":"1591699657","dateModified":"1591699657"},{"type":"update","diffId":"21564","author":"martinvonz","id":"128515","dateCreated":"1591407542","dateModified":"1591407542"}],"dateCreated":"1591407542","dateModified":"1594913281","status":"Changes Planned"},{"id":"8599","callsign":"HG","title":"rebase: remove now-unused arguments from rebasenode()","author":"martinvonz","summary":"`rebasenode()` is now finally as simple as I think it should be, and\nrebasing is now repeated grafting.","testPlan":"","lineCount":"14","dependsOn":["8598"],"reviewers":["marmoute"],"ccs":["marmoute","mercurial-patches"],"actions":[{"type":"comment","comment":"Changes planned to earlier patch in the series","author":"martinvonz","id":"130850","dateCreated":"1594913080","dateModified":"1594913080"},{"type":"plan-changes","author":"martinvonz","id":"130849","dateCreated":"1594913080","dateModified":"1594913080"},{"type":"accept","author":"marmoute","id":"128863","dateCreated":"1591811948","dateModified":"1591811948"},{"type":"comment","comment":">>! In D8599#128724, @marmoute wrote:\n> This patch seems related to D8596 which @martinvonz pointed as \"not meant to be merged\". What should we do with this diff ? is it intended for landing ? If not could get we it out of need-review and marke it RFC ?\n\nThat was on an earlier version of the series; this series is now ready.","author":"martinvonz","id":"128755","dateCreated":"1591711962","dateModified":"1591711962"},{"type":"comment","comment":"This patch seems related to D8596 which @martinvonz pointed as \"not meant to be merged\". What should we do with this diff ? is it intended for landing ? If not could get we it out of need-review and marke it RFC ?","author":"marmoute","id":"128724","dateCreated":"1591699668","dateModified":"1591699668"},{"type":"update","diffId":"21567","author":"martinvonz","id":"128529","dateCreated":"1591407581","dateModified":"1591407581"},{"type":"update","diffId":"21528","author":"martinvonz","id":"128312","dateCreated":"1590767873","dateModified":"1590767873"}],"dateCreated":"1590767873","dateModified":"1594913080","status":"Changes Planned"},{"id":"8598","callsign":"HG","title":"rebase: drop duplicate call to copies.graftcopies()","author":"martinvonz","summary":"`merge.graft()` already calls it.","testPlan":"","lineCount":"8","dependsOn":["8597"],"reviewers":["marmoute"],"ccs":["marmoute","mercurial-patches"],"actions":[{"type":"comment","comment":"Changes planned to earlier patch in the series","author":"martinvonz","id":"130848","dateCreated":"1594913069","dateModified":"1594913069"},{"type":"plan-changes","author":"martinvonz","id":"130847","dateCreated":"1594913069","dateModified":"1594913069"},{"type":"accept","author":"marmoute","id":"128862","dateCreated":"1591811886","dateModified":"1591811886"},{"type":"comment","comment":">>! In D8598#128720, @marmoute wrote:\n> This patch seems related to D8596 which @martinvonz pointed as \"not meant to be merged\". What should we do with this diff ? is it intended for landing ? If not could get we it out of need-review and marke it RFC ?\n\nThat was on an earlier version of the series; this series is now ready.","author":"martinvonz","id":"128754","dateCreated":"1591711949","dateModified":"1591711949"},{"type":"comment","comment":"This patch seems related to D8596 which @martinvonz pointed as \"not meant to be merged\". What should we do with this diff ? is it intended for landing ? If not could get we it out of need-review and marke it RFC ?","author":"marmoute","id":"128720","dateCreated":"1591699664","dateModified":"1591699664"},{"type":"update","diffId":"21566","author":"martinvonz","id":"128527","dateCreated":"1591407579","dateModified":"1591407579"},{"type":"update","diffId":"21527","author":"martinvonz","id":"128304","dateCreated":"1590767872","dateModified":"1590767872"}],"dateCreated":"1590767872","dateModified":"1594913069","status":"Changes Planned"},{"id":"8596","callsign":"HG","title":"merge: mark copies in in-memory context when merging","author":"martinvonz","summary":"Until now, `merge.update()` didn't mark copies in the\n`overlayworkingctx` (when using that). That's because we copies are\nrecorded in the `wctx` (whether that's a `workingctx` or a\n`overlayworkingctx`) in `recordupdates()`, which is not called when we\nshould not udpate the dirstate, which we should not do for in-memory\nupdates.\n\nWe had not noticed this before because rebase calls graftcopies\nafter. However, I think that using `merge.update()` with an in-memory\ncontext outside the context of rebase would lose copies.\n\nThis patch fixes the problem by first extracting the desired copies\nfrom the `action` map and then applying the changes outside of\n`recordupdates()` (and removing the copy-marking from that method).\n\nAn alternative solution would be to call `recordupdates()` also in the\nin-memory case by modifying it to call `wctx.drop()` etc (which don't\nyet exist), but that would mean that we would add a bunch of no-op\nmethods on `overlayworkingctx`, since that already knows which files\nare tracked.","testPlan":"","lineCount":"57","dependsOn":[],"reviewers":["marmoute"],"ccs":["marmoute","durin42","mercurial-patches"],"actions":[{"type":"comment","comment":">>! In D8596#130836, @martinvonz wrote:\n>>>! In D8596#130831, @marmoute wrote:\n>> Can you mark them as \"changes planned\" in the mean time to clear up yadda?\n> \n> There are no actual changes planned and I guess I figured that the base patch being marked as \"changes planned\" would be sufficient, so sure, I'll update the other ones to that status too.\n\nMy main goal here is to prevent yadda to be over 50% of content to review that is actually not to review.","author":"marmoute","id":"130846","dateCreated":"1594913062","dateModified":"1594913062"},{"type":"comment","comment":">>! In D8596#130831, @marmoute wrote:\n> Can you mark them as \"changes planned\" in the mean time to clear up yadda?\n\nThere are no actual changes planned and I guess I figured that the base patch being marked as \"changes planned\" would be sufficient, so sure, I'll update the other ones to that status too.","author":"martinvonz","id":"130836","dateCreated":"1594912986","dateModified":"1594912986"},{"type":"comment","comment":"Can you mark them as \"changes planned\" in the mean time to clear up yadda?\n","author":"marmoute","id":"130831","dateCreated":"1594910086","dateModified":"1594910086"},{"type":"comment","comment":">>! In D8596#130671, @marmoute wrote:\n> What's the conclusion here ? I feel like we decided to move in the opposite direction\n\nYes, I agree that we should make `recordupdates()` also record copies. I'll update this patch to do that eventually :)\n\n> (and to drop this series). Is that right ?\n\nMost if the series would still be unchanged, I think. I could drop this patch and replace it by another patch, but I could also reuse the Phabricator review for the new purpose. Doesn't matter much to me.","author":"martinvonz","id":"130686","dateCreated":"1594830058","dateModified":"1594830058"},{"type":"comment","comment":"What's the conclusion here ? I feel like we decided to move in the opposite direction (and to drop this series). Is that right ?","author":"marmoute","id":"130671","dateCreated":"1594829778","dateModified":"1594829778"},{"type":"inline","comment":"Yes, I was also feeling that more and more. We should probably replicate many dirstate methods on workingctx and its subclasses.","replyTo":"128913","isNewFile":"1","line":"766","lineLength":"0","path":"mercurial\/mergestate.py","diffId":"21560","author":"martinvonz","id":"128916","dateCreated":"1591897642","dateModified":"1591897642"},{"type":"plan-changes","author":"martinvonz","id":"128914","dateCreated":"1591897642","dateModified":"1591897642"},{"type":"inline","comment":"Okay, then it feel like we are going the in wrong direction and breaking the API contract here. For example, why is only part of record update move to apply update ? Does this impact our ability to execute applyupdates in parallel ? etc.\n\nIt would seems much cleaner to call recordupdates on all ctx types, don't it?","replyTo":"128879","isNewFile":"1","line":"766","lineLength":"0","path":"mercurial\/mergestate.py","diffId":"21560","author":"marmoute","id":"128913","dateCreated":"1591897156","dateModified":"1591897156"},{"type":"inline","comment":"Yes, that is correct about their roles. See commit message for my reasoning.","replyTo":"128872","isNewFile":"1","line":"766","lineLength":"0","path":"mercurial\/mergestate.py","diffId":"21560","author":"martinvonz","id":"128879","dateCreated":"1591886113","dateModified":"1591886113"},{"type":"inline","comment":"Good question! I've added a comment.","replyTo":"128871","isNewFile":"1","line":"1891","lineLength":"0","path":"mercurial\/merge.py","diffId":"21560","author":"martinvonz","id":"128878","dateCreated":"1591886113","dateModified":"1591886113"},{"type":"update","diffId":"21607","author":"martinvonz","id":"128875","dateCreated":"1591886050","dateModified":"1591886050"},{"type":"inline","comment":"Okay, so why do we have both a `applyupdates` and `recordupdates` function ? What are their respective resonsability and why is it split ?\n\nIs it that `apply` is only responsible for touching the disk content and `record` to only update internal metadata like the dirstate ? If so, moving the copies recording out of recordupdates seems wrong. ","replyTo":null,"isNewFile":"1","line":"766","lineLength":"0","path":"mercurial\/mergestate.py","diffId":"21560","author":"marmoute","id":"128872","dateCreated":"1591883159","dateModified":"1591883159"},{"type":"inline","comment":"Actually, thinking more about it, I still don't know why we should overlook rename information when overwriting. Can you clarify that point in a comment ?","replyTo":"128864","isNewFile":"1","line":"1891","lineLength":"0","path":"mercurial\/merge.py","diffId":"21560","author":"marmoute","id":"128871","dateCreated":"1591883159","dateModified":"1591883159"},{"type":"inline","comment":"no, phabricator diffing made me think we were in the following function, that takes it as an argument:\n\n```\ndef applyupdates(\n repo, actions, wctx, mctx, overwrite, wantfiledata, labels=None\n):\n```","replyTo":"128859","isNewFile":"1","line":"1891","lineLength":"0","path":"mercurial\/merge.py","diffId":"21560","author":"marmoute","id":"128864","dateCreated":"1591812212","dateModified":"1591812212"},{"type":"inline","comment":"It's defined on line 1631 and used a few times thereafter. Would you like a comment in each place it's used? I can add that in a separate patch. I don't know think there's a relevant docstring to update.","replyTo":"128848","isNewFile":"1","line":"1891","lineLength":"0","path":"mercurial\/merge.py","diffId":"21560","author":"martinvonz","id":"128859","dateCreated":"1591811656","dateModified":"1591811656"},{"type":"inline","comment":"> I don't understand this docstring. From what I see of the code, it mostly pull things from an actions dictionnary to put them in a copies dictionnary. That does not seems to involves the dirstates nor any \"recording\". Am I missing something ?\n\nI suspect that all you're missing is https:\/\/www.mercurial-scm.org\/repo\/hg\/file\/61719b9658b1\/mercurial\/mergestate.py#l758 (or maybe you just didn't infer that this was a bad copy from there) :) Fixed.\n\n","replyTo":"128847","isNewFile":"1","line":"1170","lineLength":"0","path":"mercurial\/merge.py","diffId":"21560","author":"martinvonz","id":"128858","dateCreated":"1591811656","dateModified":"1591811656"},{"type":"update","diffId":"21603","author":"martinvonz","id":"128854","dateCreated":"1591811647","dateModified":"1591811647"},{"type":"inline","comment":"I don't know what `overwrite` means and the docstring does not mention it. Can you clarify this and fix the docstring ?","replyTo":null,"isNewFile":"1","line":"1891","lineLength":"0","path":"mercurial\/merge.py","diffId":"21560","author":"marmoute","id":"128848","dateCreated":"1591810809","dateModified":"1591810809"},{"type":"inline","comment":"I don't understand this docstring. From what I see of the code, it mostly pull things from an actions dictionnary to put them in a copies dictionnary. That does not seems to involves the dirstates nor any \"recording\". Am I missing something ?","replyTo":null,"isNewFile":"1","line":"1170","lineLength":"0","path":"mercurial\/merge.py","diffId":"21560","author":"marmoute","id":"128847","dateCreated":"1591810809","dateModified":"1591810809"},{"type":"comment","comment":"I have a bunch a questions.","author":"marmoute","id":"128846","dateCreated":"1591810809","dateModified":"1591810809"},{"type":"comment","comment":">>! In D8596#128758, @marmoute wrote:\n>>>! In D8596#128750, @martinvonz wrote:\n>>>>! In D8596#128704, @marmoute wrote:\n>>>>>! In D8596#128319, @martinvonz wrote:\n>>>> This is not meant for review; I'm sending it now in case it'll be useful for @durin42's work on merge-diffs. I also included the rest of the stack to explain why I wrote the code.\n>>> \n>>> Can you add a RFC tag to this then ?\n>> \n>> I had marked it \"Changes Planned\" but I've fixed the issues and the version I uploaded a day or two ago is ready for review .\n> \n> Okay, (It would help if you reply to your own comment to state this clearly, which you now did)\n\nYep, I definitely should have. Sorry that I didn't think of doing that.\n","author":"martinvonz","id":"128759","dateCreated":"1591718787","dateModified":"1591718787"},{"type":"comment","comment":">>! In D8596#128750, @martinvonz wrote:\n>>>! In D8596#128704, @marmoute wrote:\n>>>>! In D8596#128319, @martinvonz wrote:\n>>> This is not meant for review; I'm sending it now in case it'll be useful for @durin42's work on merge-diffs. I also included the rest of the stack to explain why I wrote the code.\n>> \n>> Can you add a RFC tag to this then ?\n> \n> I had marked it \"Changes Planned\" but I've fixed the issues and the version I uploaded a day or two ago is ready for review .\n\nOkay, (It would help if you reply to your own comment to state this clearly, which you now did)","author":"marmoute","id":"128758","dateCreated":"1591717689","dateModified":"1591717727"},{"type":"comment","comment":">>! In D8596#128704, @marmoute wrote:\n>>>! In D8596#128319, @martinvonz wrote:\n>> This is not meant for review; I'm sending it now in case it'll be useful for @durin42's work on merge-diffs. I also included the rest of the stack to explain why I wrote the code.\n> \n> Can you add a RFC tag to this then ?\n\nI had marked it \"Changes Planned\" but I've fixed the issues and the version I uploaded a day or two ago is ready for review .","author":"martinvonz","id":"128750","dateCreated":"1591711464","dateModified":"1591711464"},{"type":"request-review","author":"martinvonz","id":"128748","dateCreated":"1591711464","dateModified":"1591711464"},{"type":"comment","comment":">>! In D8596#128319, @martinvonz wrote:\n> This is not meant for review; I'm sending it now in case it'll be useful for @durin42's work on merge-diffs. I also included the rest of the stack to explain why I wrote the code.\n\nCan you add a RFC tag to this then ?","author":"marmoute","id":"128704","dateCreated":"1591699544","dateModified":"1591699544"},{"type":"reject","author":"marmoute","id":"128703","dateCreated":"1591699544","dateModified":"1591699544"},{"type":"update","diffId":"21560","author":"martinvonz","id":"128497","dateCreated":"1591407457","dateModified":"1591407457"},{"type":"comment","comment":"This is not meant for review; I'm sending it now in case it'll be useful for @durin42's work on merge-diffs. I also included the rest of the stack to explain why I wrote the code.","author":"martinvonz","id":"128320","dateCreated":"1590768016","dateModified":"1590768016"},{"type":"plan-changes","author":"martinvonz","id":"128318","dateCreated":"1590768016","dateModified":"1590768016"},{"type":"update","diffId":"21525","author":"martinvonz","id":"128289","dateCreated":"1590767870","dateModified":"1590767870"}],"dateCreated":"1590767870","dateModified":"1594913062","status":"Changes Planned"},{"id":"8597","callsign":"HG","title":"rebase: use merge.graft() instead of merge.update()","author":"martinvonz","summary":"It's been possible to call `merge.graft()` here for a while (I don't\nremember which of my previous changes made it possible), but it would\nhave meant that we did a redundant `graftcopies()` call. With the fix\nto make `merge.update()` record copies in the overlayworkingctx (when\nusing that), we can now also remove the redundant `graftcopies()`\ncall. The next patch will do that.","testPlan":"","lineCount":"14","dependsOn":["8616"],"reviewers":["marmoute"],"ccs":["marmoute","mercurial-patches"],"actions":[{"type":"comment","comment":"Changes planned to earlier patch in the series","author":"martinvonz","id":"130845","dateCreated":"1594913055","dateModified":"1594913055"},{"type":"plan-changes","author":"martinvonz","id":"130844","dateCreated":"1594913055","dateModified":"1594913055"},{"type":"reclaim","author":"martinvonz","id":"130843","dateCreated":"1594913047","dateModified":"1594913047"},{"type":"comment","comment":"Changes planned to earlier patch in the series","author":"martinvonz","id":"130842","dateCreated":"1594913039","dateModified":"1594913039"},{"type":"abandon","author":"martinvonz","id":"130841","dateCreated":"1594913039","dateModified":"1594913039"},{"type":"comment","comment":"Great.","author":"marmoute","id":"128861","dateCreated":"1591811694","dateModified":"1591811694"},{"type":"accept","author":"marmoute","id":"128860","dateCreated":"1591811694","dateModified":"1591811694"},{"type":"comment","comment":">>! In D8597#128716, @marmoute wrote:\n> This patch seems related to D8596 which @martinvonz pointed as \"not meant to be merged\". What should we do with this diff ? is it intended for landing ? If not could get we it out of need-review and marke it RFC ?\n\nThat was on an earlier version of the series; this series is now ready.","author":"martinvonz","id":"128753","dateCreated":"1591711931","dateModified":"1591711931"},{"type":"comment","comment":"This patch seems related to D8596 which @martinvonz pointed as \"not meant to be merged\". What should we do with this diff ? is it intended for landing ? If not could get we it out of need-review and marke it RFC ?","author":"marmoute","id":"128716","dateCreated":"1591699660","dateModified":"1591699660"},{"type":"update","diffId":"21565","author":"martinvonz","id":"128522","dateCreated":"1591407577","dateModified":"1591407577"},{"type":"update","diffId":"21526","author":"martinvonz","id":"128297","dateCreated":"1590767871","dateModified":"1590767871"}],"dateCreated":"1590767871","dateModified":"1594913055","status":"Changes Planned"},{"id":"8595","callsign":"HG","title":"copies: make _chain() and _filter() public","author":"martinvonz","summary":"The next patch will add a call to chain(). I made _filter() public\njust for consistency.","testPlan":"","lineCount":"18","dependsOn":["8596"],"reviewers":["indygreg"],"ccs":["marmoute","mercurial-patches"],"actions":[{"type":"comment","comment":"Changes planned to earlier patch in the series","author":"martinvonz","id":"130838","dateCreated":"1594913019","dateModified":"1594913019"},{"type":"plan-changes","author":"martinvonz","id":"130837","dateCreated":"1594913019","dateModified":"1594913019"},{"type":"update","diffId":"21604","author":"martinvonz","id":"128856","dateCreated":"1591811648","dateModified":"1591811648"},{"type":"comment","comment":">>! In D8595#128708, @marmoute wrote:\n> This patch seems related to D8596 which @martinvonz pointed as \"not meant to be merged\". What should we do with this diff ? is it intended for landing ? If not could get we it out of need-review and marke it RFC ?\n\nThat was on an earlier version of the series; this series is now ready.","author":"martinvonz","id":"128751","dateCreated":"1591711898","dateModified":"1591711898"},{"type":"comment","comment":"This patch seems related to D8596 which @martinvonz pointed as \"not meant to be merged\". What should we do with this diff ? is it intended for landing ? If not could get we it out of need-review and marke it RFC ?","author":"marmoute","id":"128708","dateCreated":"1591699645","dateModified":"1591699645"},{"type":"update","diffId":"21561","author":"martinvonz","id":"128502","dateCreated":"1591407458","dateModified":"1591407458"},{"type":"accept","author":"indygreg","id":"128346","dateCreated":"1590855643","dateModified":"1590855643"},{"type":"update","diffId":"21524","author":"martinvonz","id":"128284","dateCreated":"1590767868","dateModified":"1590767868"}],"dateCreated":"1590767868","dateModified":"1594913019","status":"Changes Planned"},{"id":"6876","callsign":"HG","title":"phabricator: support automatically obsoleting old revisions of pulled commits","author":"mharbison72","summary":"This is basically an import of the `pullcreatemarkers` extension[1] from the FB\nrepo, with minor adjustments to `getmatchingdiff()` to work with modern hg.\nSince this is very phabricator specific, it makes more sense to me to bundle it\ninto the existing extension. It wasn't very obvious from the old name what\nfunctionality was provided, and it may make sense to do this in other scenarios\nbesides `hg pull`.\n\nThere are two use cases that I can see- first, ensuring that old revisions are\ncleaned up for a contributor (I seem to recall something I submitted recently\nneeded to be explicitly pruned, though most submissions do clean up\nautomatically). Second, any `hg phabread | hg import -` would otherwise need to\nbe manually cleaned up. The latter is annoying enough that I tend not to grab\nthe code and try it when reviewing.\n\nIt is currently guarded by a config option (off by default), because @marmoute\nexpressed concerns about duplicate marker creation if the pushing reviewer also\ncreates a marker. I don't think that's possible here, since the obsolete\nrevisions are explicitly excluded. But maybe there are other reasons someone\nwouldn't want older revisions obsoleted. The config name reflects the fact that\nI'm not sure if other things like import should get this too.\n\nI suspect that we could wrap a function deeper in the pull sequence to improve\nboth the code and the UX. For example, when pulling an obsolete marker, it can\nprint out a warning that the working directory parent is obsolete, but that\ndoesn't happen here. (It won't happen with this test. It *should* without the\n`--bypass` option, but doesn't.) It should also be possible to not have to\nquery the range of new revisions, and maybe it can be added to the existing\ntransaction.\n\n[1] https:\/\/bitbucket.org\/facebook\/hg-experimental\/src\/default\/hgext3rd\/pullcreatemarkers.py","testPlan":"","lineCount":"69","dependsOn":[],"reviewers":["baymax"],"ccs":["mercurial-patches","pulkit","sheehan","Kwan","mercurial-devel","marmoute"],"actions":[{"type":"plan-changes","author":"mharbison72","id":"130697","dateCreated":"1594833808","dateModified":"1594833808"},{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117510","dateCreated":"1579887103","dateModified":"1579887103"},{"type":"reject","author":"baymax","id":"117509","dateCreated":"1579887103","dateModified":"1579887103"},{"type":"inline","comment":"Right, and this is probably the typical case. (The `phabimport` alias I have imports as secret to prevent accidental push.) But secret is visible to the user, and benefits from the cleanup. Archived isn\u2019t visible (IIUC), so it probably doesn\u2019t need to be obsoleted too- especially if we\u2019re worried about marker growth.\n\n(I\u2019m also not sure how well thg handles archived, and that probably needs to be squared away first if we opt to archive instead of obsolete here.)","replyTo":"102970","isNewFile":"1","line":"216","lineLength":"0","path":"hgext\/phabricator.py","diffId":"16604","author":"mharbison72","id":"102982","dateCreated":"1570536765","dateModified":"1570536765"},{"type":"inline","comment":"I see. So maybe this should only obsolete things that have no precursors, and warn (and ignore) things that do. That means it doesn\u2019t clean up if the reviewer accidentally forgets to import with `\u2014obsolete`, but that\u2019s easy enough to fix with a copy\/paste command if A and A' are identified in the output.","replyTo":"102971","isNewFile":"1","line":"187","lineLength":"0","path":"hgext\/phabricator.py","diffId":"16604","author":"mharbison72","id":"102981","dateCreated":"1570536765","dateModified":"1570536765"},{"type":"inline","comment":"User A phasend a patch\n\n - User A phasend a changeset `A` as D1337\n - User B phabimport D1337, rebase (as `A'`) and pushes\n - User A fix critical bug in D1337 and amend it as `A''`\n - User A pull the **old** version of D1337 without the fix.\n\nIf we obsolete the **new** version of D1337 (`A''`), we are silently dropping the fix to the critical bug.\n\nIf markers were properly exchange, the evolution machinery would detect the divergence, warn the user and be able to automatically solve it. Preserving the fix to the criticial bug.\n\n","replyTo":"102947","isNewFile":"1","line":"187","lineLength":"0","path":"hgext\/phabricator.py","diffId":"16604","author":"marmoute","id":"102971","dateCreated":"1570529823","dateModified":"1570529823"},{"type":"inline","comment":"Thing could be in `secret` phase too.","replyTo":"102944","isNewFile":"1","line":"216","lineLength":"0","path":"hgext\/phabricator.py","diffId":"16604","author":"marmoute","id":"102970","dateCreated":"1570529823","dateModified":"1570529823"},{"type":"inline","comment":"I do mean **after** locking (sorry)","replyTo":"102945","isNewFile":"1","line":"225","lineLength":"0","path":"hgext\/phabricator.py","diffId":"16604","author":"marmoute","id":"102969","dateCreated":"1570529823","dateModified":"1570529823"},{"type":"inline","comment":"It looks like, based on the loop where it's used, it will obsolete \/\/all\/\/ (non public) commits that match. The only way I can think of where that happens is if I `phabimport` someone else's patches, they make updates, and then I `phabimport` again. That's why I was wondering aloud about doing this on import, but if the eventual pull cleans it all up, that may be sufficient for the use case I had in mind. I don't see how a developer would do that on their own commits with amend and friends.\n\nDo you have any ideas to detect phase divergence? And can that even happen if we're ignoring public commits?","replyTo":"102927","isNewFile":"1","line":"187","lineLength":"0","path":"hgext\/phabricator.py","diffId":"16604","author":"mharbison72","id":"102947","dateCreated":"1570508435","dateModified":"1570508435"},{"type":"inline","comment":"I wonder if it would be better in some txn hook. And then it could (I think) share the existing transaction and lock.","replyTo":"102929","isNewFile":"1","line":"192","lineLength":"0","path":"hgext\/phabricator.py","diffId":"16604","author":"mharbison72","id":"102946","dateCreated":"1570508435","dateModified":"1570508435"},{"type":"inline","comment":"You mean \/\/after\/\/ locking, correct?","replyTo":"102928","isNewFile":"1","line":"225","lineLength":"0","path":"hgext\/phabricator.py","diffId":"16604","author":"mharbison72","id":"102945","dateCreated":"1570508435","dateModified":"1570508435"},{"type":"inline","comment":"Agreed.\n\nI saw mention of the archived phase the other day; how would that (and other special phases) play here?","replyTo":"102926","isNewFile":"1","line":"216","lineLength":"0","path":"hgext\/phabricator.py","diffId":"16604","author":"mharbison72","id":"102944","dateCreated":"1570508435","dateModified":"1570508435"},{"type":"comment","comment":">>! In D6876#102925, @marmoute wrote:\n> The feature seens pretty usful, but is also a potential foot-gun\/data-loss engine. I think it is useful to take the feature, but maybe with proper documentaiton warning and turned of by efaut. I made a couple of comment about the implementation.\n\nI basically agree with the inline comments. This was an import with minimal changes as a baseline, and I didn't want to spend time making a bunch of follow ups until I gauged interest in this.\n\nAlternately, if there's concern over obsolete marker growth, should this use the archived phase instead? Since the use case is mostly around stuff a developer imports locally, I don't see much value in those markers being exchangeable. The only potential hole I see is if someone has pushed this to a non publishing repo before pulling. Then everyone else could pull the (not obsoleted) commit. But then \/\/they\/\/ would archive it on pull too, instead of N developers potentially creating N markers for the same commit.","author":"mharbison72","id":"102943","dateCreated":"1570508435","dateModified":"1570508435"},{"type":"inline","comment":"It would probably make sense to wrap the pull exchange logic instead. It would catch more instance and could reuse the same transaction.","replyTo":null,"isNewFile":"1","line":"192","lineLength":"0","path":"hgext\/phabricator.py","diffId":"16604","author":"marmoute","id":"102929","dateCreated":"1570495381","dateModified":"1570495381"},{"type":"inline","comment":"We should do the computation before locking to avoid other process updating the repo under our feet.","replyTo":null,"isNewFile":"1","line":"225","lineLength":"0","path":"hgext\/phabricator.py","diffId":"16604","author":"marmoute","id":"102928","dateCreated":"1570495381","dateModified":"1570495381"},{"type":"inline","comment":"So, this only checks the diff number, right ? So in theory, we could obsolete a later version of this, silently dropping change (instead of detecting potential phase-divergence)","replyTo":null,"isNewFile":"1","line":"187","lineLength":"0","path":"hgext\/phabricator.py","diffId":"16604","author":"marmoute","id":"102927","dateCreated":"1570495381","dateModified":"1570495381"},{"type":"inline","comment":"This should be `non public()` instead of `draft()` these could be draft.","replyTo":null,"isNewFile":"1","line":"216","lineLength":"0","path":"hgext\/phabricator.py","diffId":"16604","author":"marmoute","id":"102926","dateCreated":"1570495381","dateModified":"1570495381"},{"type":"comment","comment":"The feature seens pretty usful, but is also a potential foot-gun\/data-loss engine. I think it is useful to take the feature, but maybe with proper documentaiton warning and turned of by efaut. I made a couple of comment about the implementation.","author":"marmoute","id":"102925","dateCreated":"1570495381","dateModified":"1570495381"},{"type":"comment","comment":"@sheehan this might be of interest to you.","author":"pulkit","id":"102116","dateCreated":"1570282533","dateModified":"1570282533"},{"type":"update","diffId":"16604","author":"mharbison72","id":"100947","dateCreated":"1569388644","dateModified":"1569388644"}],"dateCreated":"1569388644","dateModified":"1594833808","status":"Changes Planned"},{"id":"7576","callsign":"HG","title":"hg-core: add configparser to library","author":"indygreg","summary":"This commit contains all the changes to the recently-imported\nRust code to make it work with our Rust library and pass our\nlinting tests.\n\nWe rename lib.rs to mod.rs to reflect it being a sub-module instead\nof a full library. We add this module to our lib.rs. We add various\npackage dependencies to Cargo.toml. We make a handful of Rust code\nupdates to reflect the new symbol locations. Finally, we add a\nparser.rs containing the boilerplate for generating a config file\nparser from the spec.pest file.\n\nAs part of adding the dependencies, some versions changed slightly\nfrom the upstream Cargo.toml, as we already had referenced a more\nmodern crate version.","testPlan":"","lineCount":"305","dependsOn":["7582"],"reviewers":["baymax"],"ccs":["mercurial-patches","marmoute","Alphare","durin42","kevincox","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"130679","dateCreated":"1594830053","dateModified":"1594830053"},{"type":"reject","author":"baymax","id":"130678","dateCreated":"1594830053","dateModified":"1594830053"},{"type":"comment","comment":"@Alphare What's your current opinion on this diff, can you mark it accepted or request change appropriately ?","author":"marmoute","id":"124052","dateCreated":"1584659236","dateModified":"1584659236"},{"type":"comment","comment":"I'm a little lost on the state of this. It looks like we need to downgrade the required Rust version?","author":"durin42","id":"114846","dateCreated":"1578513514","dateModified":"1578513514"},{"type":"inline","comment":"I know it doesn't matter at all, but the timing of this issue is just too funny not to share: https:\/\/github.com\/tokio-rs\/bytes\/issues\/340","replyTo":"111969","isNewFile":"1","line":"14","lineLength":"0","path":"rust\/hg-core\/Cargo.toml","diffId":"18547","author":"Alphare","id":"112098","dateCreated":"1576180674","dateModified":"1576180674"},{"type":"inline","comment":"I wonder about this dependency. It uses 4 `usize` for every slice of bytes, and adds some overhead, albeit minimal, that I am trying to justify.\nAre we looking at reaping the benefits down the line? The crate itself is good quality, maintained by the Tokio people, so I'm not *too* worried about it being pre-1.0, but do we need this? ","replyTo":null,"isNewFile":"1","line":"14","lineLength":"0","path":"rust\/hg-core\/Cargo.toml","diffId":"18547","author":"Alphare","id":"111969","dateCreated":"1576140492","dateModified":"1576140492"},{"type":"inline","comment":"\"The current minimum required Rust version is 1.36\". This disqualifies this crate from being used in `hg-core` right now. Good news is that it is supposed to offer improvements over existing `std` types like `Mutex` and the like, so it's nothing that would be hard to replace. \n\nAlso, I've seen complaints online about the lack of benchmarks of `parking_lot` against `std` types to back-up their claims for performance. I have not looked into it myself.","replyTo":null,"isNewFile":"1","line":"19","lineLength":"0","path":"rust\/hg-core\/Cargo.toml","diffId":"18547","author":"Alphare","id":"111455","dateCreated":"1575896446","dateModified":"1575896446"},{"type":"update","diffId":"18547","author":"indygreg","id":"111419","dateCreated":"1575774207","dateModified":"1575774207"},{"type":"update","diffId":"18541","author":"indygreg","id":"111381","dateCreated":"1575759414","dateModified":"1575759414"},{"type":"update","diffId":"18536","author":"indygreg","id":"111341","dateCreated":"1575749872","dateModified":"1575749872"}],"dateCreated":"1575749872","dateModified":"1594830053","status":"Needs Revision"},{"id":"8677","callsign":"HG","title":"heptapod: use basename of tests in skiplist in CI (issue6351)","author":"pulkit","summary":"In heptapod CI we create a skiplist of test-check* and don't want to run in\nother test suites as we have specific test suite for checks. However the\nskiplist was not working fine because we were putting test names in form of\n`tests\/test-check*` in it which does not work with our test runner.\n\nWe get the basename of the file and then put it in skiplist.","testPlan":"","lineCount":"2","dependsOn":[],"reviewers":[],"ccs":["mercurial-patches"],"actions":[{"type":"plan-changes","author":"pulkit","id":"129612","dateCreated":"1593771992","dateModified":"1593771992"},{"type":"update","diffId":"21761","author":"pulkit","id":"129607","dateCreated":"1593771898","dateModified":"1593771898"}],"dateCreated":"1593771898","dateModified":"1593771992","status":"Changes Planned"},{"id":"7786","callsign":"HG","title":"update: add --abort option in hg update command (issue4404)","author":"khanchi97","summary":"Here is, what --abort option is basically doing:\n1) hg resolve --unmark, then\n2) hg resolve --all --tool :local\n3) hg up <original ctx> --tool :local\n\nWhere,\nstep 1) is to mark all the files conflicted as unresolved (marking *all*\nfiles to make sure that it also mark the files which might have been\nresolved by user in meantime)\n\nstep 2) resolve all the conflicting files using `--tool :local`\n\nstep 3) update to the revision where it was checkedout before running the\nhg update, using `--tool :local`\n\nUse of `--tool :local` while updating to old revision (step3) make sure that\nit will not hit merge conflict at the time of update. And since we are using\nthe same tool (:local) as we used at the time of resolution (step2) it makes\nsure that we have exact changes in working directory as it was before IIUC.\n\nAdded tests demonstrate the behaviour of new flag.","testPlan":"","lineCount":"97","dependsOn":[],"reviewers":["mharbison72"],"ccs":["mharbison72","mercurial-devel"],"actions":[{"type":"comment","comment":"This looks like a respin of D6735. Can you take a look at my comments in there about subrepos, and incorporate the appropriate tests? (I also didn't side by side compare the existing tests, so I'm not sure if there are things tested in that revision that aren't tested here.)","author":"mharbison72","id":"114439","dateCreated":"1578121196","dateModified":"1578121196"},{"type":"reject","author":"mharbison72","id":"114437","dateCreated":"1578121196","dateModified":"1578121196"},{"type":"update","diffId":"19034","author":"khanchi97","id":"114431","dateCreated":"1578063940","dateModified":"1578063940"}],"dateCreated":"1578063940","dateModified":"1592806928","status":"Needs Revision"},{"id":"6735","callsign":"HG","title":"update: added support for --abort flag(issue4404)","author":"taapas1128","summary":"This patch adds functionality to abort a conflicted\nupdate. A new function `hg.abortupdate()` is added for\nthe purpose which has a helper function\n`hg._unmarkandresolvelocal()` which deals with the\nconflicts occured.\n\nResults are shown in tests.","testPlan":"","lineCount":"210","dependsOn":[],"reviewers":["durin42","mharbison72"],"ccs":["joerg.sonnenberger","mercurial-patches","khanchi97","durin42","mharbison72","pulkit","mjpieters","mercurial-devel"],"actions":[{"type":"comment","comment":">>! In D6735#123875, @khanchi97 wrote:\n>>>! In D6735#100642, @mharbison72 wrote:\n>> Here's a case I stumbled upon that is a problem. It looks like it thinks it isn't in the middle of an update, but .hgsubstate isn't put back to the pre-update state.\n>> \n>> ```\n>> diff --git a\/tests\/test-subrepo.t b\/tests\/test-subrepo.t\n>> --- a\/tests\/test-subrepo.t\n>> +++ b\/tests\/test-subrepo.t\n>> @@ -1027,10 +1027,38 @@ filesystem (see also issue4583))\n>> > [extensions]\n>> > fakedirstatewritetime = $TESTDIR\/fakedirstatewritetime.py\n>> > EOF\n>> + $ hg -R repo st -S\n>> + ? s\/b\n>> + $ hg -R repo diff -S\n>> + $ hg -R repo log -r .\n>> + changeset: 0:c4018e9aea1b\n>> + user: test\n>> + date: Thu Jan 01 00:00:00 1970 +0000\n>> + summary: 1\n>> +\n>> + $ cat repo\/.hgsubstate\n>> + f7b1eb17ad24730a1651fccd46c43826d1bbc2ac s\n>> $ hg -R repo update\n>> b: untracked file differs\n>> abort: untracked files in working directory differ from files in requested revision (in subrepository \"s\")\n> @mharbison72 I am bit confused here.\n> 1) Since `hg -R repo update` resulted with an abort then why we have dirty working directory now? Isn't transaction rollback worked correctly?\n\nTwo things to keep in mind.\n1) updates aren't transactions\n2) even if they were, a transaction is within *one* repo.\n\nWhen you update with subrepos, you check for dirty from the top, recurse to the bottom, and on the way up you update the subrepo. So in the simple case of parent repo P and subrepo S, you check P for dirty (recursively), then update S, then update P. If something goes wrong updating P, S is not rolled back.\n\n> 2) Also if you run `hg status` it says \"To continue: run `hg update .`\" but I don't think it's really a \"continue\", since we are still on the same changeset where we ran the first update command and running `hg update .` won't take us to the changeset we wanted to go.\n\nMaybe it needs to continue if it did a partial checkout? IDK when the parent in dirstate is updated- before or after all files are checked out.\n\n> 3) I found that for interrupted update (only for some particular kind of interrupted update) we store target node value in `.hg\/updatestate` but I couldn't find where we exactly use that value. I found some code which check if that file exists but not one where we use the value stored in that file.\n\nSorry, I'm not sure about that either. I'd imagine it's for the --continue case though. Maybe that isn't fully implemented yet?","author":"mharbison72","id":"123876","dateCreated":"1584398748","dateModified":"1584398748"},{"type":"comment","comment":">>! In D6735#100642, @mharbison72 wrote:\n> Here's a case I stumbled upon that is a problem. It looks like it thinks it isn't in the middle of an update, but .hgsubstate isn't put back to the pre-update state.\n> \n> ```\n> diff --git a\/tests\/test-subrepo.t b\/tests\/test-subrepo.t\n> --- a\/tests\/test-subrepo.t\n> +++ b\/tests\/test-subrepo.t\n> @@ -1027,10 +1027,38 @@ filesystem (see also issue4583))\n> > [extensions]\n> > fakedirstatewritetime = $TESTDIR\/fakedirstatewritetime.py\n> > EOF\n> + $ hg -R repo st -S\n> + ? s\/b\n> + $ hg -R repo diff -S\n> + $ hg -R repo log -r .\n> + changeset: 0:c4018e9aea1b\n> + user: test\n> + date: Thu Jan 01 00:00:00 1970 +0000\n> + summary: 1\n> +\n> + $ cat repo\/.hgsubstate\n> + f7b1eb17ad24730a1651fccd46c43826d1bbc2ac s\n> $ hg -R repo update\n> b: untracked file differs\n> abort: untracked files in working directory differ from files in requested revision (in subrepository \"s\")\n@mharbison72 I am bit confused here.\n1) Since `hg -R repo update` resulted with an abort then why we have dirty working directory now? Isn't transaction rollback worked correctly?\n2) Also if you run `hg status` it says \"To continue: run `hg update .`\" but I don't think it's really a \"continue\", since we are still on the same changeset where we ran the first update command and running `hg update .` won't take us to the changeset we wanted to go.\n3) I found that for interrupted update (only for some particular kind of interrupted update) we store target node value in `.hg\/updatestate` but I couldn't find where we exactly use that value. I found some code which check if that file exists but not one where we use the value stored in that file.\n> [255]\n> + $ hg -R repo update --abort\n> + abort: no update in progress\n> + [255]\n> + $ hg -R repo diff -S\n> + diff -r c4018e9aea1b .hgsubstate\n> + --- a\/.hgsubstate Thu Jan 01 00:00:00 1970 +0000\n> + +++ b\/.hgsubstate Thu Jan 01 00:00:00 1970 +0000\n> + @@ -1,1 +1,1 @@\n> + -f7b1eb17ad24730a1651fccd46c43826d1bbc2ac s\n> + +cc505f09a8b2644adffa368adb4abc6f70d07bc0 s\n> + $ hg -R repo log -r .\n> + changeset: 0:c4018e9aea1b\n> + user: test\n> + date: Thu Jan 01 00:00:00 1970 +0000\n> + summary: 1\n> +\n> +\n> $ cat >> repo\/.hg\/hgrc <<EOF\n> > [extensions]\n> > fakedirstatewritetime = !\n> ```\n> \n> Another good way to induce this .hgsubstate issue is to `hg pull -u` on a repo, where the remote subrepo isn't available. You don't need http for this- you can just rename the remote subrepo.\n\n","author":"khanchi97","id":"123875","dateCreated":"1584395223","dateModified":"1584395223"},{"type":"comment","comment":"Here's a case I stumbled upon that is a problem. It looks like it thinks it isn't in the middle of an update, but .hgsubstate isn't put back to the pre-update state.\n\n```\ndiff --git a\/tests\/test-subrepo.t b\/tests\/test-subrepo.t\n--- a\/tests\/test-subrepo.t\n+++ b\/tests\/test-subrepo.t\n@@ -1027,10 +1027,38 @@ filesystem (see also issue4583))\n > [extensions]\n > fakedirstatewritetime = $TESTDIR\/fakedirstatewritetime.py\n > EOF\n+ $ hg -R repo st -S\n+ ? s\/b\n+ $ hg -R repo diff -S\n+ $ hg -R repo log -r .\n+ changeset: 0:c4018e9aea1b\n+ user: test\n+ date: Thu Jan 01 00:00:00 1970 +0000\n+ summary: 1\n+\n+ $ cat repo\/.hgsubstate\n+ f7b1eb17ad24730a1651fccd46c43826d1bbc2ac s\n $ hg -R repo update\n b: untracked file differs\n abort: untracked files in working directory differ from files in requested revision (in subrepository \"s\")\n [255]\n+ $ hg -R repo update --abort\n+ abort: no update in progress\n+ [255]\n+ $ hg -R repo diff -S\n+ diff -r c4018e9aea1b .hgsubstate\n+ --- a\/.hgsubstate Thu Jan 01 00:00:00 1970 +0000\n+ +++ b\/.hgsubstate Thu Jan 01 00:00:00 1970 +0000\n+ @@ -1,1 +1,1 @@\n+ -f7b1eb17ad24730a1651fccd46c43826d1bbc2ac s\n+ +cc505f09a8b2644adffa368adb4abc6f70d07bc0 s\n+ $ hg -R repo log -r .\n+ changeset: 0:c4018e9aea1b\n+ user: test\n+ date: Thu Jan 01 00:00:00 1970 +0000\n+ summary: 1\n+\n+\n $ cat >> repo\/.hg\/hgrc <<EOF\n > [extensions]\n > fakedirstatewritetime = !\n```\n\nAnother good way to induce this .hgsubstate issue is to `hg pull -u` on a repo, where the remote subrepo isn't available. You don't need http for this- you can just rename the remote subrepo.","author":"mharbison72","id":"100642","dateCreated":"1568603671","dateModified":"1568603671"},{"type":"comment","comment":"Oops, meant to flag changes needed too.","author":"mharbison72","id":"100435","dateCreated":"1568266462","dateModified":"1568266462"},{"type":"reject","author":"mharbison72","id":"100434","dateCreated":"1568266462","dateModified":"1568266462"},{"type":"comment","comment":">>! In D6735#100392, @durin42 wrote:\n> This looks good to me. Does anyone else have comments? @mharbison72 are you happy with the subrepo test coverage?\n\nI forgot about this, thanks for the reminder. @taapas1128 is correct- the subrepos aren't being initialized as subrepos (i.e. there's no .hgsub file). I'll try to play with this more Friday or over the weekend.","author":"mharbison72","id":"100433","dateCreated":"1568266403","dateModified":"1568266403"},{"type":"comment","comment":"@durin42 I don't think the subrepos are properly initialized in the tests. I would be updating them soon.","author":"taapas1128","id":"100416","dateCreated":"1568219239","dateModified":"1568219239"},{"type":"comment","comment":"This looks good to me. Does anyone else have comments? @mharbison72 are you happy with the subrepo test coverage?","author":"durin42","id":"100392","dateCreated":"1568215450","dateModified":"1568215450"},{"type":"accept","author":"durin42","id":"100391","dateCreated":"1568215450","dateModified":"1568215450"},{"type":"inline","comment":"@mharbison72 Have a look. I have updated the diff.","replyTo":"98964","isNewFile":"1","line":"2092","lineLength":"0","path":"tests\/test-merge-tools.t","diffId":"16251","author":"taapas1128","id":"99147","dateCreated":"1566483696","dateModified":"1566483696"},{"type":"update","diffId":"16294","author":"taapas1128","id":"99144","dateCreated":"1566483618","dateModified":"1566483618"},{"type":"inline","comment":"When you add more tests, please include some with 1 dirty subrepo, and then another where the first subrepo is already merged\/resolved, and the second subrepo is dirty and pending a merge\/resolve. If it simplifies the initial implementation to detect a dirty subrepo and then abort the `--abort` before it starts, that seems fine.","replyTo":"98944","isNewFile":"1","line":"2092","lineLength":"0","path":"tests\/test-merge-tools.t","diffId":"16251","author":"mharbison72","id":"98964","dateCreated":"1566232323","dateModified":"1566232323"},{"type":"inline","comment":"this line is not required.","replyTo":null,"isNewFile":"1","line":"992","lineLength":"0","path":"mercurial\/hg.py","diffId":"16262","author":"pulkit","id":"98962","dateCreated":"1566228426","dateModified":"1566228426"},{"type":"comment","comment":"Nice start! If I remember correctly, the mergestate stores the local version of the file. We can use that directly instead.","author":"pulkit","id":"98961","dateCreated":"1566228426","dateModified":"1566228426"},{"type":"update","diffId":"16262","author":"taapas1128","id":"98945","dateCreated":"1566135118","dateModified":"1566135118"},{"type":"inline","comment":"I have created a separate file will add more tests.","replyTo":"98873","isNewFile":"1","line":"2092","lineLength":"0","path":"tests\/test-merge-tools.t","diffId":"16251","author":"taapas1128","id":"98944","dateCreated":"1566133737","dateModified":"1566133737"},{"type":"update","diffId":"16261","author":"taapas1128","id":"98942","dateCreated":"1566133621","dateModified":"1566133621"},{"type":"inline","comment":"we need to hide this, maybe use more low level APIs. I haven't look at code in details, will try to look soon.","replyTo":null,"isNewFile":"1","line":"2129","lineLength":"0","path":"tests\/test-merge-tools.t","diffId":"16251","author":"pulkit","id":"98874","dateCreated":"1566070139","dateModified":"1566070139"},{"type":"inline","comment":"I suggest taking `update --abort` tests in a new file as we will need to extensively test that.","replyTo":null,"isNewFile":"1","line":"2092","lineLength":"0","path":"tests\/test-merge-tools.t","diffId":"16251","author":"pulkit","id":"98873","dateCreated":"1566070139","dateModified":"1566070139"},{"type":"update","diffId":"16251","author":"taapas1128","id":"98867","dateCreated":"1566069370","dateModified":"1566069370"},{"type":"update","diffId":"16250","author":"taapas1128","id":"98866","dateCreated":"1566058705","dateModified":"1566058705"},{"type":"update","diffId":"16249","author":"taapas1128","id":"98861","dateCreated":"1566058419","dateModified":"1566058419"}],"dateCreated":"1566058419","dateModified":"1592806928","status":"Needs Revision"},{"id":"8064","callsign":"HG","title":"split: add a --single flag to only ask for one split","author":"rdamazio","summary":"The majority of split invocations only want to split a revision in two,\nso this allows them to do that without getting a second chunk selector.\nI thought of making a generic \"max_splits\" flag, but that seemed like\noverkill.","testPlan":"","lineCount":"72","dependsOn":["7630"],"reviewers":["baymax"],"ccs":["mercurial-patches","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"128590","dateCreated":"1591637695","dateModified":"1591637695"},{"type":"reject","author":"baymax","id":"128589","dateCreated":"1591637695","dateModified":"1591637695"},{"type":"update","diffId":"19813","author":"rdamazio","id":"118999","dateCreated":"1580542108","dateModified":"1580542108"}],"dateCreated":"1580542108","dateModified":"1591637696","status":"Needs Revision"},{"id":"7630","callsign":"HG","title":"absorb: make the absorbed changeset be automatically \"evolved\"","author":"rdamazio","summary":"When a committed changeset is absorbed, this will make it so it's not used for\ncomputing the absorption, but is still recreated at the destination.","testPlan":"","lineCount":"92","dependsOn":["7631"],"reviewers":["baymax"],"ccs":["mercurial-patches","marmoute","pulkit","martinvonz","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"128586","dateCreated":"1591637695","dateModified":"1591637695"},{"type":"reject","author":"baymax","id":"128585","dateCreated":"1591637695","dateModified":"1591637695"},{"type":"comment","comment":"It looks like this series is introducing UI change of the same kind as the one @martinvonz is looking into for `hg copy`. I'll try to have a look at both of them tomorrow.","author":"marmoute","id":"120511","dateCreated":"1581460836","dateModified":"1581460836"},{"type":"comment","comment":">>! In D7630#118997, @rdamazio wrote:\n>>>>! In D7630#117270, @marmoute wrote:\n>>>>>! In D7630#115320, @pulkit wrote:\n>>>>>> This results in an empty commit which is not similar to what rebase or evolve will generally result in after `D7631` unless `ui.allowemptycommit=True` is set. I think good behavior is to obsolete the absorbed changeset in favour of either it's parent or one of the revs in which it was absorbed. \n>>>>> \n>>>>> I made a related comment on the parent patch before I realized that this patch adds obsmarker handling. My suggestion there was to mark all the commits that got absorbed into as successors, and if there's anything left in the absorbed commit, that would be yet another successor. Would that work?\n>>>> \n>>>> Yep, that sounds good.\n>> \n>> I'm fine with doing this, but is there an efficient way to detect that it became empty?\n> \n> And by \"this\" I meant I'm fine with making it disappear if allowemptycommit is False. I don't fully understand how markers help accomplish that.\n\nWhen you try to create an empty commit, you'll get a `None` back for the nodeid (from `repo.commitctx()`, IIRC), so check for that.","author":"martinvonz","id":"120510","dateCreated":"1581445623","dateModified":"1581445623"},{"type":"update","diffId":"19982","author":"rdamazio","id":"119745","dateCreated":"1581045062","dateModified":"1581045062"},{"type":"update","diffId":"19980","author":"rdamazio","id":"119741","dateCreated":"1581044151","dateModified":"1581044151"},{"type":"comment","comment":">>>! In D7630#117270, @marmoute wrote:\n>>>>! In D7630#115320, @pulkit wrote:\n>>>>> This results in an empty commit which is not similar to what rebase or evolve will generally result in after `D7631` unless `ui.allowemptycommit=True` is set. I think good behavior is to obsolete the absorbed changeset in favour of either it's parent or one of the revs in which it was absorbed. \n>>>> \n>>>> I made a related comment on the parent patch before I realized that this patch adds obsmarker handling. My suggestion there was to mark all the commits that got absorbed into as successors, and if there's anything left in the absorbed commit, that would be yet another successor. Would that work?\n>>> \n>>> Yep, that sounds good.\n> \n> I'm fine with doing this, but is there an efficient way to detect that it became empty?\n\nAnd by \"this\" I meant I'm fine with making it disappear if allowemptycommit is False. I don't fully understand how markers help accomplish that.\n","author":"rdamazio","id":"118997","dateCreated":"1580541152","dateModified":"1580541152"},{"type":"comment","comment":">>! In D7630#115300, @pulkit wrote:\n> This results in an empty commit which is not similar to what rebase or evolve will generally result in after `D7631` unless `ui.allowemptycommit=True` is set. I think good behavior is to obsolete the absorbed changeset in favour of either it's parent or one of the revs in which it was absorbed. \n\nIt's not *always* empty - if there had been lines that it failed absorb (because it couldn't find where to absorb into), those would be left in the commit.\n\n>>! In D7630#117270, @marmoute wrote:\n>>>! In D7630#115320, @pulkit wrote:\n>>>> This results in an empty commit which is not similar to what rebase or evolve will generally result in after `D7631` unless `ui.allowemptycommit=True` is set. I think good behavior is to obsolete the absorbed changeset in favour of either it's parent or one of the revs in which it was absorbed. \n>>> \n>>> I made a related comment on the parent patch before I realized that this patch adds obsmarker handling. My suggestion there was to mark all the commits that got absorbed into as successors, and if there's anything left in the absorbed commit, that would be yet another successor. Would that work?\n>> \n>> Yep, that sounds good.\n\nI'm fine with doing this, but is there an efficient way to detect that it became empty?\n\n> This means generate split+fold markers. That is going to be fun to deal with :-). I dont' really have any much better idea however (the alternative seems to use simple prune markers, which is meh).\n\nI'm not following this part - why do you need markers at all?\n(you can argue whether you want them - but I don't see why you *need* them)\n","author":"rdamazio","id":"118992","dateCreated":"1580541029","dateModified":"1580541029"},{"type":"update","diffId":"19812","author":"rdamazio","id":"118991","dateCreated":"1580541026","dateModified":"1580541026"},{"type":"comment","comment":">>! In D7630#115320, @pulkit wrote:\n>>> This results in an empty commit which is not similar to what rebase or evolve will generally result in after `D7631` unless `ui.allowemptycommit=True` is set. I think good behavior is to obsolete the absorbed changeset in favour of either it's parent or one of the revs in which it was absorbed. \n>> \n>> I made a related comment on the parent patch before I realized that this patch adds obsmarker handling. My suggestion there was to mark all the commits that got absorbed into as successors, and if there's anything left in the absorbed commit, that would be yet another successor. Would that work?\n> \n> Yep, that sounds good.\n\nThis means generate split+fold markers. That is going to be fun to deal with :-). I dont' really have any much better idea however (the alternative seems to use simple prune markers, which is meh).","author":"marmoute","id":"117270","dateCreated":"1579797461","dateModified":"1579797461"},{"type":"comment","comment":">> This results in an empty commit which is not similar to what rebase or evolve will generally result in after `D7631` unless `ui.allowemptycommit=True` is set. I think good behavior is to obsolete the absorbed changeset in favour of either it's parent or one of the revs in which it was absorbed. \n> \n> I made a related comment on the parent patch before I realized that this patch adds obsmarker handling. My suggestion there was to mark all the commits that got absorbed into as successors, and if there's anything left in the absorbed commit, that would be yet another successor. Would that work?\n\nYep, that sounds good.\n","author":"pulkit","id":"115320","dateCreated":"1578937060","dateModified":"1578937078"},{"type":"comment","comment":">>! In D7630#112603, @rdamazio wrote:\n> Sorry for the upload mess (though it's arguably a `phabsend` bug :) ). Tried uploading the \"right\" way now.\n\nI reported that as https:\/\/bz.mercurial-scm.org\/show_bug.cgi?id=6241.\n\n>>! In D7630#115300, @pulkit wrote:\n> This results in an empty commit which is not similar to what rebase or evolve will generally result in after `D7631` unless `ui.allowemptycommit=True` is set. I think good behavior is to obsolete the absorbed changeset in favour of either it's parent or one of the revs in which it was absorbed. \n\nI made a related comment on the parent patch before I realized that this patch adds obsmarker handling. My suggestion there was to mark all the commits that got absorbed into as successors, and if there's anything left in the absorbed commit, that would be yet another successor. Would that work?","author":"martinvonz","id":"115319","dateCreated":"1578936945","dateModified":"1578936945"},{"type":"comment","comment":"This results in an empty commit which is not similar to what rebase or evolve will generally result in after `D7631` unless `ui.allowemptycommit=True` is set. I think good behavior is to obsolete the absorbed changeset in favour of either it's parent or one of the revs in which it was absorbed. ","author":"pulkit","id":"115300","dateCreated":"1578931057","dateModified":"1578931057"},{"type":"update","diffId":"19049","author":"rdamazio","id":"114543","dateCreated":"1578357967","dateModified":"1578357967"},{"type":"update","diffId":"18874","author":"rdamazio","id":"113354","dateCreated":"1576741000","dateModified":"1576741000"},{"type":"update","diffId":"18844","author":"rdamazio","id":"113173","dateCreated":"1576644413","dateModified":"1576644413"},{"type":"update","diffId":"18842","author":"rdamazio","id":"113169","dateCreated":"1576644149","dateModified":"1576644149"},{"type":"update","diffId":"18729","author":"rdamazio","id":"112606","dateCreated":"1576304727","dateModified":"1576304727"},{"type":"comment","comment":"Sorry for the upload mess (though it's arguably a `phabsend` bug :) ). Tried uploading the \"right\" way now.","author":"rdamazio","id":"112603","dateCreated":"1576303334","dateModified":"1576303334"},{"type":"update","diffId":"18727","author":"rdamazio","id":"112600","dateCreated":"1576303329","dateModified":"1576303329"},{"type":"comment","comment":">>! In D7630#112243, @rdamazio wrote:\n> (on mobile) I think it was `hg phabsend -r .+.^`\n\nOhh, that makes some sense that phabsend might do it backwards if you pass the revisions backwards, but that's still clearly a bug. I'll report it in bugzilla if it's not already there. I'll manually update the parent\/child relationship on these reviews for now.\n","author":"martinvonz","id":"112244","dateCreated":"1576220268","dateModified":"1576220268"},{"type":"comment","comment":"(on mobile) I think it was `hg phabsend -r .+.^`\n\n - {F454947, layout=link}","author":"rdamazio","id":"112243","dateCreated":"1576219938","dateModified":"1576219938"},{"type":"inline","comment":"Oh, it's added in D7631, which is marked as a *child* of this review. How did that happen? `hg phabsend` should set the relationships automatically. How did you run that command? Just `hg phabsend .^::.` or similar? Or did you manually mark D7631 as a child?","replyTo":"112239","isNewFile":"1","line":"67","lineLength":"0","path":"tests\/test-absorb-rev.t","diffId":"18665","author":"martinvonz","id":"112241","dateCreated":"1576219632","dateModified":"1576219632"},{"type":"inline","comment":"`hg absorb` has a `-r` flag? Did you forgot to upload some ancestors of this commit?","replyTo":null,"isNewFile":"1","line":"67","lineLength":"0","path":"tests\/test-absorb-rev.t","diffId":"18665","author":"martinvonz","id":"112239","dateCreated":"1576217462","dateModified":"1576217462"},{"type":"update","diffId":"18665","author":"rdamazio","id":"112225","dateCreated":"1576216538","dateModified":"1576216538"}],"dateCreated":"1576216538","dateModified":"1591637695","status":"Needs Revision"},{"id":"8579","callsign":"HG","title":"context: avoid computing status twice when comparing among revisions","author":"rom1dep","summary":"","testPlan":"","lineCount":"13","dependsOn":[],"reviewers":["marmoute","durin42"],"ccs":["durin42","marmoute","mercurial-patches"],"actions":[{"type":"comment","comment":"Breaks many tests for status code, sadly.\n\n(Regrettably, I've already lost that output, and I need to go get lunch with family.)","author":"durin42","id":"128128","dateCreated":"1590511068","dateModified":"1590511068"},{"type":"reject","author":"durin42","id":"128127","dateCreated":"1590511068","dateModified":"1590511068"},{"type":"comment","comment":"This looks fine.","author":"marmoute","id":"128062","dateCreated":"1590500737","dateModified":"1590500737"},{"type":"accept","author":"marmoute","id":"128061","dateCreated":"1590500737","dateModified":"1590500737"},{"type":"comment","comment":"No real justification for, only found it weird, and since we have to do that test anyway I didn't think it would make perfs worse,\nDidn't run tests on it, though.","author":"rom1dep","id":"128003","dateCreated":"1590389462","dateModified":"1590389462"},{"type":"update","diffId":"21466","author":"rom1dep","id":"127999","dateCreated":"1590389282","dateModified":"1590389282"}],"dateCreated":"1590389282","dateModified":"1590511069","status":"Needs Revision"},{"id":"8571","callsign":"HG","title":"test: make test-doctest.py not assume it's run from a mercurial repo","author":"jcristau","summary":"This assumption fails when building and running tests from a source\ntarball, e.g.","testPlan":"","lineCount":"16","dependsOn":[],"reviewers":[],"ccs":["mercurial-patches"],"actions":[{"type":"comment","comment":"Need to fix some stuff, I'll get back to this tomorrow.","author":"jcristau","id":"127919","dateCreated":"1589920648","dateModified":"1589920648"},{"type":"plan-changes","author":"jcristau","id":"127918","dateCreated":"1589920648","dateModified":"1589920648"},{"type":"update","diffId":"21450","author":"jcristau","id":"127903","dateCreated":"1589916511","dateModified":"1589916511"}],"dateCreated":"1589916511","dateModified":"1589920648","status":"Changes Planned"},{"id":"6026","callsign":"HG","title":"lock: Improve the waiting for lock message which will help newcomers\n(issue6081)","author":"akshjain.jain74","summary":"","testPlan":"","lineCount":"71","dependsOn":[],"reviewers":["baymax"],"ccs":["mercurial-patches","marmoute","pulkit","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"126762","dateCreated":"1588061930","dateModified":"1588061930"},{"type":"reject","author":"baymax","id":"126761","dateCreated":"1588061930","dateModified":"1588061930"},{"type":"comment","comment":"Gentle ping on this. This has been around for a long time, what's the status of it?","author":"marmoute","id":"117290","dateCreated":"1579799546","dateModified":"1579799546"},{"type":"comment","comment":">>! In D6026#88552, @pulkit wrote:\n> I am not sure the new message is much helpful. As JordiGH and others pointed out on IRC, it will definitely be helpful if we can show which operation has the lock right now.\n> \n> Something like:\n> \n> `waiting for lock on working directory of b held by process '*' running <cmd-name> on host '*'`\n\nSo for which commands we can show this message, like i got message when i run hg commit --amend sometimes ","author":"akshjain.jain74","id":"88558","dateCreated":"1551900706","dateModified":"1551900706"},{"type":"inline","comment":"I accept these changes while running test, if i am not changing this then it will cause test failing","replyTo":"88554","isNewFile":"0","line":"18","lineLength":"0","path":"tests\/test-lock-badness.t","diffId":"14277","author":"akshjain.jain74","id":"88557","dateCreated":"1551893473","dateModified":"1551893473"},{"type":"comment","comment":"okay @pulkit let me work upon your suggestion and ","author":"akshjain.jain74","id":"88556","dateCreated":"1551893473","dateModified":"1551893473"},{"type":"inline","comment":"The output is not correctly aligned. ","replyTo":null,"isNewFile":"1","line":"62","lineLength":"0","path":"tests\/test-lock-badness.t","diffId":"14291","author":"pulkit","id":"88555","dateCreated":"1551879636","dateModified":"1551879636"},{"type":"inline","comment":"still here are unrealted changes.","replyTo":"88052","isNewFile":"0","line":"18","lineLength":"0","path":"tests\/test-lock-badness.t","diffId":"14277","author":"pulkit","id":"88554","dateCreated":"1551879636","dateModified":"1551879636"},{"type":"inline","comment":"unrelated changes.","replyTo":null,"isNewFile":"1","line":"155","lineLength":"0","path":"tests\/test-extdiff.t","diffId":"14291","author":"pulkit","id":"88553","dateCreated":"1551879636","dateModified":"1551879636"},{"type":"comment","comment":"I am not sure the new message is much helpful. As JordiGH and others pointed out on IRC, it will definitely be helpful if we can show which operation has the lock right now.\n\nSomething like:\n\n`waiting for lock on working directory of b held by process '*' running <cmd-name> on host '*'`","author":"pulkit","id":"88552","dateCreated":"1551879636","dateModified":"1551879636"},{"type":"update","diffId":"14291","author":"akshjain.jain74","id":"88119","dateCreated":"1551530162","dateModified":"1551530162"},{"type":"comment","comment":"@pulkit done changes as per your suggestion in lock file too but what did you meant by storelock?","author":"akshjain.jain74","id":"88059","dateCreated":"1551392049","dateModified":"1551392049"},{"type":"update","diffId":"14279","author":"akshjain.jain74","id":"88056","dateCreated":"1551391885","dateModified":"1551391885"},{"type":"inline","comment":"unrelated changes in the test file here and below.","replyTo":null,"isNewFile":"0","line":"18","lineLength":"0","path":"tests\/test-lock-badness.t","diffId":"14277","author":"pulkit","id":"88052","dateCreated":"1551389487","dateModified":"1551389487"},{"type":"inline","comment":"remove which file manually to continue?\n\nI think we should delete the `If it still fails, ..... remove the file manually to continue` part.","replyTo":null,"isNewFile":"1","line":"316","lineLength":"0","path":"hgext\/journal.py","diffId":"14277","author":"pulkit","id":"88051","dateCreated":"1551389487","dateModified":"1551389487"},{"type":"inline","comment":"This is only for locking namejournal.lock and not for working directory lock and store lock. We need to improve message there too.","replyTo":null,"isNewFile":"1","line":"310","lineLength":"0","path":"hgext\/journal.py","diffId":"14277","author":"pulkit","id":"88050","dateCreated":"1551389487","dateModified":"1551389487"},{"type":"update","diffId":"14277","author":"akshjain.jain74","id":"88048","dateCreated":"1551388596","dateModified":"1551388596"},{"type":"update","diffId":"14274","author":"akshjain.jain74","id":"88039","dateCreated":"1551376882","dateModified":"1551376882"},{"type":"update","diffId":"14273","author":"akshjain.jain74","id":"88038","dateCreated":"1551373745","dateModified":"1551373745"},{"type":"update","diffId":"14272","author":"akshjain.jain74","id":"88037","dateCreated":"1551373367","dateModified":"1551373367"},{"type":"update","diffId":"14271","author":"akshjain.jain74","id":"88036","dateCreated":"1551373151","dateModified":"1551373151"},{"type":"comment","comment":"Ya I am sending that just trying to find out the file","author":"akshjain.jain74","id":"87909","dateCreated":"1551191027","dateModified":"1551191027"},{"type":"comment","comment":"This patch does not changes any code. It only changes some test output. You need to change the error message in the code.","author":"pulkit","id":"87908","dateCreated":"1551190913","dateModified":"1551190913"},{"type":"update","diffId":"14244","author":"akshjain.jain74","id":"87894","dateCreated":"1551173448","dateModified":"1551173448"}],"dateCreated":"1551173448","dateModified":"1588061931","status":"Needs Revision"},{"id":"6123","callsign":"HG","title":"similar: add condition to avoid Zerodivisonerror in function _score() (issue6099)","author":"akshjain.jain74","summary":"","testPlan":"","lineCount":"4","dependsOn":[],"reviewers":["durin42","baymax"],"ccs":["mercurial-patches","marmoute","av6","pulkit","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"126758","dateCreated":"1588061929","dateModified":"1588061929"},{"type":"reject","author":"baymax","id":"126757","dateCreated":"1588061929","dateModified":"1588061929"},{"type":"comment","comment":"Gentle ping on this. This has been around for a long time, what's the status of it?","author":"marmoute","id":"117292","dateCreated":"1579799599","dateModified":"1579799599"},{"type":"inline","comment":"yes actually \ud83d\ude05 i did'nt noticed that ","replyTo":"89412","isNewFile":"1","line":"68","lineLength":"0","path":"mercurial\/similar.py","diffId":"14487","author":"akshjain.jain74","id":"89432","dateCreated":"1552659675","dateModified":"1552659675"},{"type":"update","diffId":"14508","author":"akshjain.jain74","id":"89430","dateCreated":"1552659596","dateModified":"1552659596"},{"type":"comment","comment":"thanks for the review\n","author":"akshjain.jain74","id":"89422","dateCreated":"1552658279","dateModified":"1552658279"},{"type":"comment","comment":">>! In D6123#89410, @pulkit wrote:\n> Can you try to add a test for this?\n\nyes i can definitely try to add test for this ","author":"akshjain.jain74","id":"89421","dateCreated":"1552658267","dateModified":"1552658267"},{"type":"inline","comment":"no need for this else. you can `return 0` without else.","replyTo":null,"isNewFile":"1","line":"68","lineLength":"0","path":"mercurial\/similar.py","diffId":"14487","author":"pulkit","id":"89412","dateCreated":"1552657477","dateModified":"1552657477"},{"type":"inline","comment":"we can do `if lengths:` here.","replyTo":null,"isNewFile":"1","line":"66","lineLength":"0","path":"mercurial\/similar.py","diffId":"14487","author":"pulkit","id":"89411","dateCreated":"1552657477","dateModified":"1552657477"},{"type":"comment","comment":"Can you try to add a test for this?","author":"pulkit","id":"89410","dateCreated":"1552657477","dateModified":"1552657477"},{"type":"update","diffId":"14487","author":"akshjain.jain74","id":"89272","dateCreated":"1552508232","dateModified":"1552508232"},{"type":"comment","comment":"actually i am not getting what can be the proper topic for this :(","author":"akshjain.jain74","id":"89249","dateCreated":"1552501010","dateModified":"1552501010"},{"type":"comment","comment":"sorry for that , but can you tell me in what condition this function will return none value?","author":"akshjain.jain74","id":"89248","dateCreated":"1552500860","dateModified":"1552500860"},{"type":"inline","comment":"`None > 1` is still an issue, see my comment above.","replyTo":null,"isNewFile":"1","line":"66","lineLength":"1","path":"mercurial\/similar.py","diffId":"14482","author":"av6","id":"89240","dateCreated":"1552500162","dateModified":"1552500162"},{"type":"comment","comment":"Okay, let's go over #1 in https:\/\/www.mercurial-scm.org\/wiki\/ContributingChanges#Submission_checklist once more. If you want to know what a good \"topic\" is, look at what other people do. How patches that get accepted generally look. How bug-fixing commits are worded.\n\nSecondly, about that capitalization. I'm sorry if this is some sort of silly autocorrect that's doing it for you, I really hope you're not writing commit messages on a phone.","author":"av6","id":"89239","dateCreated":"1552500162","dateModified":"1552500162"},{"type":"update","diffId":"14482","author":"akshjain.jain74","id":"89237","dateCreated":"1552498479","dateModified":"1552498479"},{"type":"comment","comment":"Sorry for the various mistake\n I will correct everything in an hour thanks","author":"akshjain.jain74","id":"89222","dateCreated":"1552470438","dateModified":"1552470438"},{"type":"inline","comment":"This returns None in some cases, and code that uses `_score()` and `score()` tries to compare it to an integer. In Python3 `None > 1` raises TypeError.","replyTo":null,"isNewFile":"1","line":"67","lineLength":"0","path":"mercurial\/similar.py","diffId":"14477","author":"av6","id":"89221","dateCreated":"1552469028","dateModified":"1552469028"},{"type":"inline","comment":"This is some... interesting syntax. Is this valid Python?","replyTo":null,"isNewFile":"1","line":"66","lineLength":"1","path":"mercurial\/similar.py","diffId":"14477","author":"av6","id":"89220","dateCreated":"1552468824","dateModified":"1552468824"},{"type":"comment","comment":"I find it troubling that we now have contributors that don't follow #1 in https:\/\/www.mercurial-scm.org\/wiki\/ContributingChanges#Submission_checklist. Potentially #4 too (as Pulkit commented).\n\nSeriously, the title is terrible at describing what this patch fixes and where. The commit message could briefly mention why\/when this condition is even required.","author":"av6","id":"89219","dateCreated":"1552468824","dateModified":"1552468824"},{"type":"comment","comment":"Oh sorry ,my bad I think that is by mistake I will correct it now\nIthink while committing I added that file by mistake","author":"akshjain.jain74","id":"89217","dateCreated":"1552468624","dateModified":"1552468624"},{"type":"inline","comment":"Is this change required for this patch?","replyTo":null,"isNewFile":"1","line":"1127","lineLength":"0","path":"hgext\/histedit.py","diffId":"14477","author":"pulkit","id":"89214","dateCreated":"1552467285","dateModified":"1552467285"},{"type":"update","diffId":"14477","author":"akshjain.jain74","id":"89176","dateCreated":"1552414170","dateModified":"1552414170"}],"dateCreated":"1552414170","dateModified":"1588061930","status":"Needs Revision"},{"id":"6027","callsign":"HG","title":"mq: make unshelve to apply on modified mq patch (issue4318)","author":"navaneeth.suresh","summary":"unshelve wasn't working on a modified mq patch. I added checks for\nnot aborting on a modified mq patch in both rebase and mq.\n\nChecking `repo.vfs.exists('unshelverebasestate')` works in rebase,\nnot in mq. I used `cmdutil.unfinishedstates` to find `shelvedstate`\nin mq.","testPlan":"","lineCount":"29","dependsOn":[],"reviewers":["martinvonz","baymax"],"ccs":["mercurial-patches","marmoute","yuja","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"126754","dateCreated":"1588061928","dateModified":"1588061928"},{"type":"reject","author":"baymax","id":"126753","dateCreated":"1588061928","dateModified":"1588061928"},{"type":"comment","comment":"Waht'a sup on this. Seems to be open for a long while.","author":"marmoute","id":"117296","dateCreated":"1579799857","dateModified":"1579799857"},{"type":"comment","comment":"> It doesn't make sense to check the existence of 'shelvedstate' in a static\n> table.\n> \n> Can't we somehow get around the mq in a similar way to shelve.getcommitfunc()?\n> I don't think it's good idea to rely on state files saved on disk.\n\nI felt that the only workaround to stop aborting unshelve on a modified mq patch should be adding a check on `mq.abortifwdirpatched()`. Will try to investigate in `shelve.getcommitfunc()` for sure. Thanks.","author":"navaneeth.suresh","id":"89928","dateCreated":"1553624502","dateModified":"1553624502"},{"type":"comment","comment":"> --- a\/hgext\/mq.py\n> +++ b\/hgext\/mq.py\n> @@ -3518,7 +3518,10 @@\n> delattr(self.unfiltered(), r'mq')\n> \n> def abortifwdirpatched(self, errmsg, force=False):\n> - if self.mq.applied and self.mq.checkapplied and not force:\n> + shelveinprogress = any('shelvedstate' in state\n> + for state in cmdutil.unfinishedstates)\n> + if (self.mq.applied and self.mq.checkapplied and not force and\n> + not shelveinprogress):\n\nIt doesn't make sense to check the existence of 'shelvedstate' in a static\ntable.\n\nCan't we somehow get around the mq in a similar way to shelve.getcommitfunc()?\nI don't think it's good idea to rely on state files saved on disk.","author":"yuja","id":"89919","dateCreated":"1553552983","dateModified":"1553552983"},{"type":"comment","comment":"Gentle ping for review.","author":"navaneeth.suresh","id":"89906","dateCreated":"1553450952","dateModified":"1553450952"},{"type":"update","diffId":"14400","author":"navaneeth.suresh","id":"88740","dateCreated":"1552069564","dateModified":"1552069564"},{"type":"comment","comment":"Ping for review.","author":"navaneeth.suresh","id":"88530","dateCreated":"1551851154","dateModified":"1551851154"},{"type":"update","diffId":"14245","author":"navaneeth.suresh","id":"87900","dateCreated":"1551183856","dateModified":"1551183856"}],"dateCreated":"1551183856","dateModified":"1588061929","status":"Needs Revision"},{"id":"7716","callsign":"HG","title":"rust-discovery: partial switch to typestate pattern","author":"gracinet","summary":"The `PartialDiscovery` object owns two data fields that are\nlazily evaluated: the set of undecided revisions, and the\nchildren cache. That laziness is known to be essential for\nperformance.\n\nIn the previous version, we were using `Option<T>`, which led\nus to methods such as `ensure_undecided()` followed by calls to\n`self.undecided.as_ref().unwrap()`, as it was the simplest way\nto avoid reference sharing problems, but that wasn't\nsatisfying. Human readers knew that panicking was indeed\nimpossible, but that wasn't enforced by the compiler.\n\nWe had something similar yet less pervasive with the early\nrelease of `target_heads`.\n\nThe reviewer, Kevin Cox, then suggested to use a code pattern\nknown as typestate: different types to represent the successive\nstages, with the second one always having an undecided set.\n\nThis is what we are doing here. Now we have two state types:\n`OnlyCommon` and `WithUndecided`.\nOnly the first has the `target_heads` member; only the second\nhas the `undecided` member.\n\nIt makes the code a bit longer, because we have to make\n`PartialDiscovery` a wrapper enum for identical consumption\nwithin hg-cpython and reexpose the public interface.\nBut it makes the inner code more focused, clearer and\nbetter checked by the compiler. A few further simplifications\nwill be made in following changesets thanks to this.\n\nA key point that we didn't know how to solve\nin the first version was the in-place mutation of that wrapper\nenum, provided by the `mutate_undecided()` method.\n\nThis is partial because we don't address the children cache.\nWe'll do that in a follow-up also.\n\nAlso some methods and doc-comments have been kept on the inner\nstructs for readability of this changesets, but they will\nbe factorized on the wrapper enum in a next move","testPlan":"","lineCount":"381","dependsOn":[],"reviewers":["martinvonz"],"ccs":["mercurial-patches","marmoute","martinvonz","Alphare","durin42","kevincox","mercurial-devel"],"actions":[{"type":"comment","comment":">>! In D7716#126417, @marmoute wrote:\n> cc @Alphare is this still relevant ?\n\nIt is. @gracinet told me he would want to come back to this series when he has time. Since it's a cleanup series it's not urgent in any way, but we would all like to have this upstream some day.","author":"Alphare","id":"126506","dateCreated":"1587628319","dateModified":"1587628319"},{"type":"comment","comment":"cc @Alphare is this still relevant ?","author":"marmoute","id":"126417","dateCreated":"1587570881","dateModified":"1587570881"},{"type":"comment","comment":"I'm gonna give it a try, yes. About the namings, I'm thinking of `<Cheap>` and `<Expensive>`. It doesn't describe the contents, but it's really clear about the intent.","author":"gracinet","id":"114210","dateCreated":"1577622485","dateModified":"1577622485"},{"type":"comment","comment":">>! In D7716#114043, @gracinet wrote:\n> @martinvonz yes, I've thinked of it after I made this one, but somehow I thought this was enough for a first try.\n\nIt seems like it would be a lot of churn to take this patch and then a follow-up that rewrites it. I'd be much happier to take a patch that cleaner version right away (and it sounds like we both think it would be cleaner).\n\n> \n> Yes, we could have `PartialDiscovery<Start>`, and `PartialDiscovery<Computed>`, with `Start` being a pure marker, and `Computed` actually holding the undecided set and the children cache (anticipating on a later changeset), that would be more elegant and it would better organize the boiler plate.\n> \n> Don't hesitate if you come up with better namings.\n\nI haven't even reviewed in enough detail to know what the states represent, so I don't have any suggestions yet :)","author":"martinvonz","id":"114044","dateCreated":"1577486308","dateModified":"1577486308"},{"type":"comment","comment":"@martinvonz yes, I've thinked of it after I made this one, but somehow I thought this was enough for a first try.\n\nYes, we could have `PartialDiscovery<Start>`, and `PartialDiscovery<Computed>`, with `Start` being a pure marker, and `Computed` actually holding the undecided set and the children cache (anticipating on a later changeset), that would be more elegant and it would better organize the boiler plate.\n\nDon't hesitate if you come up with better namings.","author":"gracinet","id":"114043","dateCreated":"1577485532","dateModified":"1577485532"},{"type":"comment","comment":"Did you consider encoding the state in a type parameter to `PartialDiscovery`? I think that would make the call sites simpler. See the last variation on http:\/\/cliffle.com\/blog\/rust-typestate\/ for what I mean.","author":"martinvonz","id":"113817","dateCreated":"1577468534","dateModified":"1577468534"},{"type":"reject","author":"martinvonz","id":"113816","dateCreated":"1577468534","dateModified":"1577468534"},{"type":"comment","comment":"@durin42 this Diffrential and its descendants are what I've told you about in our latest chat: implementing suggestions by @kevincox for a much cleaner an robust code.\nI intend to provide the upcoming rust-nodemap series using the same kind of pattern. I believe @Alphare wants to clean up Dirstate related code in similar ways.","author":"gracinet","id":"113739","dateCreated":"1577196081","dateModified":"1577196081"},{"type":"update","diffId":"18924","author":"gracinet","id":"113682","dateCreated":"1577195389","dateModified":"1577195389"}],"dateCreated":"1577195389","dateModified":"1587628319","status":"Needs Revision"},{"id":"3444","callsign":"HG","title":"tests: comprehensively test exit handling","author":"indygreg","summary":"Rust `hg` currently has some test failures around exit handling.\nThis commit establishes some centralized tests around exit handling so\nthat we can unify the behavior of our Rust frontend and `python`.\n\nThere are some added tests that use a value other than an integer\nor None for the exit code. The docs for sys.exit() say such a value\nis allowed. However, Mercurial currently crashes in this case. Upcoming\ncommits will teach Mercurial to handle these values.\n\nThis does introduce a few Python 3 test failures. However, this test\nalready has a few failures. And the failures being introduced should\nmostly go away with subsequent commits. So I think this is acceptable.","testPlan":"","lineCount":"91","dependsOn":[],"reviewers":["durin42","marmoute"],"ccs":["mercurial-patches","marmoute","durin42","yuja","mercurial-devel"],"actions":[{"type":"comment","comment":"Baymax does not catch stuff in `Accepted` state, but this diff is over 2 years old, so resubmit if still relevant.","author":"marmoute","id":"126431","dateCreated":"1587571085","dateModified":"1587571085"},{"type":"reject","author":"marmoute","id":"126430","dateCreated":"1587571085","dateModified":"1587571085"},{"type":"comment","comment":"This LG, esp with D3445 which appears to be its child, but D3445 still needs rebased AFAICT","author":"durin42","id":"57781","dateCreated":"1527794332","dateModified":"1527794332"},{"type":"accept","author":"durin42","id":"57779","dateCreated":"1527794332","dateModified":"1527794332"},{"type":"comment","comment":"> > I generally like the direction of this series, but I think there's no point\n> > to extend Mercurial's exit code handling to support all weird Python types.\n> >\n> > Only ints and (None for 0) are ever valid.\n> \n> \n> The reason I did this is because from the context or `rhg`, we don't have CPython's default exit handling to fall back on. Our choices are:\n> \n> 1. Reimplement CPython's exit\/error handling in Rust\n> 2. Reimplement CPython's exit\/error handling in Python in dispatch [so the end state is more well-defined]\n> 3. Do something crude in `rhg` when we hit special cases that CPython would normally deal with.\n> \n> Since extensions could do weird things, I figured 2 was the best option.\n\nI don't fully understand the situation in `rhg`, but maybe we can instead\nfix `scmutil.callcatch()` to either translate non-int SystemExit to integer\nor raise ProgrammingError as a bad use of sys.exit() in hg. No SystemExit\nshould be raised outside of the callcatch().\n\nI'm against allowing command functions to return any objects other than\nint or None because it's useless.","author":"yuja","id":"56045","dateCreated":"1526104337","dateModified":"1526104337"},{"type":"comment","comment":">>! In D3444#54922, @yuja wrote:\n> I generally like the direction of this series, but I think there's no point\n> to extend Mercurial's exit code handling to support all weird Python types.\n> \n> Only ints and (None for 0) are ever valid.\n\nThe reason I did this is because from the context or `rhg`, we don't have CPython's default exit handling to fall back on. Our choices are:\n\n1. Reimplement CPython's exit\/error handling in Rust\n2. Reimplement CPython's exit\/error handling in Python in dispatch [so the end state is more well-defined]\n3. Do something crude in `rhg` when we hit special cases that CPython would normally deal with.\n\nSince extensions could do weird things, I figured 2 was the best option.\n\nBut I'll take a look at this series again and re-evaluate if we can simplify things. I just thought I'd brain dump on what I'm thinking.","author":"indygreg","id":"56014","dateCreated":"1526097317","dateModified":"1526097317"},{"type":"comment","comment":"I generally like the direction of this series, but I think there's no point\nto extend Mercurial's exit code handling to support all weird Python types.\n\nOnly ints and (None for 0) are ever valid.","author":"yuja","id":"54923","dateCreated":"1525609756","dateModified":"1525609756"},{"type":"update","diffId":"8459","author":"indygreg","id":"54808","dateCreated":"1525579871","dateModified":"1525579871"}],"dateCreated":"1525579871","dateModified":"1587571085","status":"Needs Revision"},{"id":"2873","callsign":"HG","title":"remotenames: add functionality to override -B flag of push","author":"pulkit","summary":"This patch adds a new config option which can be used to override the `-B` flag\nof push command. If config is set to true, changesets will be pushed to that\nbookmark on the server. This is equivalent to `--to` flag of remotenames and\ninfinitepush.\n\nAfter this patch if config is set to true, the behavior will be:\n\n * Normal push without -B flag: no behavior change\n * specifying one bookmark using -B flag: changesets will be pushed to that\n bookmark on the server, as explained above. Bookmark pushed will be on\n the head most revision of the changesets pushed.\n * specifying multiple bookmarks using -B flag: no behavior change, the same\n behavior as it's today without this config option\n * specifying multiple topologcial heads to push: no behvaior change\n\nThere needs some extra logic to update the remotenames state locally after the\npush since we know that the bookmark will now be at a known updated location.","testPlan":"","lineCount":"356","dependsOn":[],"reviewers":["indygreg","marmoute"],"ccs":["mercurial-patches","marmoute","smf","indygreg","mercurial-devel"],"actions":[{"type":"comment","comment":"Baymax does not catch stuff in `Accepted` state, but this diff is over 2 years old, so resubmit if still relevant.","author":"marmoute","id":"126426","dateCreated":"1587571035","dateModified":"1587571035"},{"type":"reject","author":"marmoute","id":"126425","dateCreated":"1587571035","dateModified":"1587571035"},{"type":"comment","comment":">>! In D2873#52100, @indygreg wrote:\n>>>! In D2873#52025, @smf wrote:\n>>>>! In D2873#52021, @indygreg wrote:\n>>> Looks good!\n>> \n>> I'm very heavily against this direction. Changing the behavior of push (even in this extension) is something I've always considered outside the scope of remotenames. Having another extension that changes push behavior (e.g. bookmark-push) is where I think this should go so that remotenames is just that: keeping track of remote names.\n> \n> I think there's room for this feature to live outside of remotenames. But currently I think it is the best place for it, since remotenames is the closest thing we have to... tracking remote names. We can always alias the old config option in the future if we move this functionality elsewhere.\n\nOne of the biggest regrets I have about the original remotenames, is the modifying of push (and some default) behavior. The `--to` is small enough (and I guess fine enough) for now but I absolutely and strongly believe that all the other behavior modifications should stay in an out-of-core repo for now. My goal is to split my remotenames repo to be based off of core's remotenames (basically only having the behavior changing patches there).","author":"smf","id":"52118","dateCreated":"1523482769","dateModified":"1523482769"},{"type":"comment","comment":">>! In D2873#52025, @smf wrote:\n>>>! In D2873#52021, @indygreg wrote:\n>> Looks good!\n> \n> I'm very heavily against this direction. Changing the behavior of push (even in this extension) is something I've always considered outside the scope of remotenames. Having another extension that changes push behavior (e.g. bookmark-push) is where I think this should go so that remotenames is just that: keeping track of remote names.\n\nI think there's room for this feature to live outside of remotenames. But currently I think it is the best place for it, since remotenames is the closest thing we have to... tracking remote names. We can always alias the old config option in the future if we move this functionality elsewhere.","author":"indygreg","id":"52100","dateCreated":"1523480112","dateModified":"1523480112"},{"type":"comment","comment":">>! In D2873#52021, @indygreg wrote:\n> Looks good!\n\nI'm very heavily against this direction. Changing the behavior of push (even in this extension) is something I've always considered outside the scope of remotenames. Having another extension that changes push behavior (e.g. bookmark-push) is where I think this should go so that remotenames is just that: keeping track of remote names.","author":"smf","id":"52026","dateCreated":"1523467971","dateModified":"1523467971"},{"type":"inline","comment":"Nit: \"exist\". This can be fixed in flight.","replyTo":null,"isNewFile":"1","line":"113","lineLength":"0","path":"hgext\/remotenames.py","diffId":"7286","author":"indygreg","id":"52023","dateCreated":"1523467769","dateModified":"1523467769"},{"type":"comment","comment":"Looks good!","author":"indygreg","id":"52022","dateCreated":"1523467769","dateModified":"1523467769"},{"type":"accept","author":"indygreg","id":"52021","dateCreated":"1523467769","dateModified":"1523467769"},{"type":"comment","comment":"A gentle reminder for reviewing this series. If this config option gets in, we can use it in infinitepush extension too where for now we have overridden `-B` flag in a hacky way.","author":"pulkit","id":"48737","dateCreated":"1522601487","dateModified":"1522601487"},{"type":"update","diffId":"7286","author":"pulkit","id":"47560","dateCreated":"1522064849","dateModified":"1522064849"},{"type":"inline","comment":"What happens if we're pushing multiple heads? I suspect this will choose a head\/revision arbitrarily - maybe depending on the `-r` arguments to `hg push`.\n\nI think we need to validate that the outgoing revs are in a single DAG head and we should then pick the rev that is the DAG head.\n\nPlease add test coverage for multiple `-r` arguments and `-r` arguments that resolve to multiple heads.","replyTo":null,"isNewFile":"1","line":"99","lineLength":"0","path":"hgext\/remotenames.py","diffId":"7249","author":"indygreg","id":"47382","dateCreated":"1521831360","dateModified":"1521831360"},{"type":"inline","comment":"Nit: what is `--create`?","replyTo":null,"isNewFile":"1","line":"101","lineLength":"0","path":"hgext\/remotenames.py","diffId":"7249","author":"indygreg","id":"47381","dateCreated":"1521831360","dateModified":"1521831360"},{"type":"inline","comment":"Strictly speaking, we should probably wrap `exchange._pushdiscoverybookmarks` so other extensions can get involved. But I think this is fine.","replyTo":null,"isNewFile":"1","line":"287","lineLength":"0","path":"hgext\/remotenames.py","diffId":"7249","author":"indygreg","id":"47380","dateCreated":"1521831360","dateModified":"1521831360"},{"type":"comment","comment":"I'm happy with this feature.\n\nBut the code needs work around multiple revisions\/heads before it can be queued.","author":"indygreg","id":"47379","dateCreated":"1521831360","dateModified":"1521831360"},{"type":"reject","author":"indygreg","id":"47378","dateCreated":"1521831360","dateModified":"1521831360"},{"type":"update","diffId":"7249","author":"pulkit","id":"47274","dateCreated":"1521704112","dateModified":"1521704112"},{"type":"update","diffId":"7103","author":"pulkit","id":"46423","dateCreated":"1521448561","dateModified":"1521448561"},{"type":"comment","comment":"I am not sure the functionality and config names should go to core or not, so I have introduced them in this extension. Also suggestions for better config names are welcome.","author":"pulkit","id":"46265","dateCreated":"1521212432","dateModified":"1521212432"},{"type":"update","diffId":"7061","author":"pulkit","id":"46148","dateCreated":"1521121763","dateModified":"1521121763"}],"dateCreated":"1521121763","dateModified":"1587571035","status":"Needs Revision"},{"id":"2875","callsign":"HG","title":"remotenames: introduce a config option to allow creation of remote bookmarks","author":"pulkit","summary":"This patch introduces another config option which if set to true, we can create\nnew bookmarks on the server using push command. An earlier patch added\ncapability to push to a certain bookmark on the server. If bookmark was not\nalready present on the server, we errored out. With\nremotenames.createremotebookmark config set, the push will create that bookmark\non the server.\n\nThis series serves as a great feature for people who use bookmarks as after this\nyou can push changesets to a bookmark which does not exists locally. In other\nwords, you can push your changesets to a bookmark without having it locally.\n\nThis series will help people in having a non-local bookmark workflow involving\nremotenames.\n\nThe functionality added in this patch is equivalent to --create flag to push\ncommand added by hgremotenames extension.","testPlan":"","lineCount":"166","dependsOn":[],"reviewers":["indygreg","marmoute"],"ccs":["mercurial-patches","marmoute","mercurial-devel"],"actions":[{"type":"comment","comment":"Baymax does not catch stuff in `Accepted` state, but this diff is over 2 years old, so resubmit if still relevant.","author":"marmoute","id":"126421","dateCreated":"1587571026","dateModified":"1587571026"},{"type":"reject","author":"marmoute","id":"126420","dateCreated":"1587571026","dateModified":"1587571026"},{"type":"accept","author":"indygreg","id":"52032","dateCreated":"1523468132","dateModified":"1523468132"},{"type":"update","diffId":"7288","author":"pulkit","id":"47564","dateCreated":"1522064875","dateModified":"1522064875"},{"type":"update","diffId":"7251","author":"pulkit","id":"47276","dateCreated":"1521704137","dateModified":"1521704137"},{"type":"update","diffId":"7105","author":"pulkit","id":"46425","dateCreated":"1521448583","dateModified":"1521448583"},{"type":"update","diffId":"7063","author":"pulkit","id":"46164","dateCreated":"1521121786","dateModified":"1521121786"}],"dateCreated":"1521121786","dateModified":"1587571027","status":"Needs Revision"},{"id":"7577","callsign":"HG","title":"hg-core: implement Mercurial's config file discovery logic","author":"indygreg","summary":"The imported Facebook code for locating Mercurial config files\ndiffered from what Mercurial itself does. This commit modifies the\nlogic to match what Mercurial currently does.\n\nAs part of this, we added some crate dependencies. We could probably\navoid these dependencies if we want. But these crates are quite popular\nand useful and I imagine we'll end up using them eventually.\n\nWe should probably add some test coverage of this code...","testPlan":"","lineCount":"148","dependsOn":["7576"],"reviewers":["kevincox","Alphare","baymax"],"ccs":["mercurial-patches","durin42","kevincox","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"126413","dateCreated":"1587570782","dateModified":"1587570782"},{"type":"reject","author":"baymax","id":"126412","dateCreated":"1587570782","dateModified":"1587570782"},{"type":"accept","author":"Alphare","id":"111521","dateCreated":"1575896924","dateModified":"1575896924"},{"type":"inline","comment":"I believe this can just be `.flatten()`.","replyTo":null,"isNewFile":"1","line":"145","lineLength":"0","path":"rust\/hg-core\/src\/configparser\/config.rs","diffId":"18544","author":"kevincox","id":"111453","dateCreated":"1575894221","dateModified":"1575894221"},{"type":"accept","author":"kevincox","id":"111452","dateCreated":"1575894221","dateModified":"1575894221"},{"type":"update","diffId":"18544","author":"indygreg","id":"111399","dateCreated":"1575759436","dateModified":"1575759436"},{"type":"update","diffId":"18537","author":"indygreg","id":"111349","dateCreated":"1575749873","dateModified":"1575749873"}],"dateCreated":"1575749873","dateModified":"1587570782","status":"Needs Revision"},{"id":"7717","callsign":"HG","title":"rust-discovery: restoring add_missing cheap early return","author":"gracinet","summary":"In case the iterator of missing revisions argument turns out\nto be empty, we need to refrain from computing the undecided\nset. This way, we'll benefit from subsequent add_common_revisions\nuntil there is an actually meaningful add_missing_revisions.\n\nTo do this with the typestate pattern, that means the early\nreturn has to happen before potential transition into an\nWithUndecided","testPlan":"","lineCount":"23","dependsOn":["7716"],"reviewers":["Alphare","baymax"],"ccs":["mercurial-patches","durin42","kevincox","mjpieters","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"126409","dateCreated":"1587570781","dateModified":"1587570781"},{"type":"reject","author":"baymax","id":"126408","dateCreated":"1587570781","dateModified":"1587570781"},{"type":"accept","author":"Alphare","id":"114421","dateCreated":"1578044801","dateModified":"1578044801"},{"type":"update","diffId":"18925","author":"gracinet","id":"113690","dateCreated":"1577195395","dateModified":"1577195395"}],"dateCreated":"1577195395","dateModified":"1587570781","status":"Needs Revision"},{"id":"7718","callsign":"HG","title":"rust-directory: simplify bidirectional sampling","author":"gracinet","summary":"Thanks to the typestate pattern, we don't have a\ncomplicated management of borrows to perform in\nthat method with the early return condition and\nthe comment was just obsolete.","testPlan":"","lineCount":"9","dependsOn":["7717"],"reviewers":["Alphare","baymax"],"ccs":["mercurial-patches","durin42","kevincox","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"126405","dateCreated":"1587570780","dateModified":"1587570780"},{"type":"reject","author":"baymax","id":"126404","dateCreated":"1587570780","dateModified":"1587570780"},{"type":"accept","author":"Alphare","id":"114422","dateCreated":"1578044870","dateModified":"1578044870"},{"type":"update","diffId":"18926","author":"gracinet","id":"113698","dateCreated":"1577195401","dateModified":"1577195401"}],"dateCreated":"1577195401","dateModified":"1587570780","status":"Needs Revision"},{"id":"7719","callsign":"HG","title":"rust-discovery: children cache as typestate transition","author":"gracinet","summary":"As of 8c9a6adec67a, we were actually using\nthe children cache right away in `add_missing_revisions`,\nthe method that also triggers the undecided set computation\n(see that changeset description for the corresponding\nperformance discussion).\n\nThis means we don't need a third typestate for the children\ncache: `WithUndecided` can always have it.\n\nIt is clear that `compute_children_cache` does not have\nto be tied to the `WithUndecided` struct anymore. We may\nmove it to `hg::dagops` in a later move.","testPlan":"","lineCount":"63","dependsOn":["7718"],"reviewers":["Alphare","baymax"],"ccs":["mercurial-patches","durin42","kevincox","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"126401","dateCreated":"1587570779","dateModified":"1587570779"},{"type":"reject","author":"baymax","id":"126400","dateCreated":"1587570779","dateModified":"1587570779"},{"type":"accept","author":"Alphare","id":"114423","dateCreated":"1578045124","dateModified":"1578045124"},{"type":"update","diffId":"18927","author":"gracinet","id":"113706","dateCreated":"1577195409","dateModified":"1577195409"}],"dateCreated":"1577195409","dateModified":"1587570779","status":"Needs Revision"},{"id":"7720","callsign":"HG","title":"rust-discovery: moved some methods to the wrapper enum","author":"gracinet","summary":"In the primary switch to the typestate pattern, these\nmethods have been kept on the `WithUndecided` struct, that\nhad most of the original methods of `PartialDiscovery`, so\nthat the change would be readable.\n\nBut we feel it makes more sense to have them on the wrapper\nenum.\n\n`common_heads` would also be a candidate for a last stage method,\nwe wouldn't need that lenghty warning docstring that it's not\nrelevant if `is-complete` is `true`","testPlan":"","lineCount":"44","dependsOn":["7719"],"reviewers":["Alphare","baymax"],"ccs":["mercurial-patches","durin42","kevincox","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"126397","dateCreated":"1587570778","dateModified":"1587570778"},{"type":"reject","author":"baymax","id":"126396","dateCreated":"1587570778","dateModified":"1587570778"},{"type":"accept","author":"Alphare","id":"114424","dateCreated":"1578045272","dateModified":"1578045272"},{"type":"update","diffId":"18928","author":"gracinet","id":"113715","dateCreated":"1577195416","dateModified":"1577195416"}],"dateCreated":"1577195416","dateModified":"1587570778","status":"Needs Revision"},{"id":"7721","callsign":"HG","title":"rust-discovery: postponing random generator init","author":"gracinet","summary":"This is an example of the benefits we get with the\ntypestape pattern: we can cleanly postpone the\nseeding and initialisation of the random generator.\n\nThis makes the `default()` method a bit cheaper. Its point\nis that its output is a placeholder not meand to be really used,\nbut if that happened, it would now be with the knowledge that\nthe seed hasn't been initialized (and possible seeding after\nmorphing into a discovery with undecided set)","testPlan":"","lineCount":"41","dependsOn":["7720"],"reviewers":["Alphare","baymax"],"ccs":["mercurial-patches","durin42","kevincox","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"126393","dateCreated":"1587570777","dateModified":"1587570777"},{"type":"reject","author":"baymax","id":"126392","dateCreated":"1587570777","dateModified":"1587570777"},{"type":"accept","author":"Alphare","id":"114425","dateCreated":"1578045385","dateModified":"1578045385"},{"type":"update","diffId":"18929","author":"gracinet","id":"113723","dateCreated":"1577195423","dateModified":"1577195423"}],"dateCreated":"1577195423","dateModified":"1587570777","status":"Needs Revision"},{"id":"7722","callsign":"HG","title":"rust-discovery: simplifying add_missing_revisions()","author":"gracinet","summary":"with the removal of the various ensure() it's become\nclear that this doesn't have error cases any more, and we didn't\nneed the full match at the end.","testPlan":"","lineCount":"21","dependsOn":["7721"],"reviewers":["Alphare","baymax"],"ccs":["mercurial-patches","durin42","kevincox","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"126389","dateCreated":"1587570776","dateModified":"1587570776"},{"type":"reject","author":"baymax","id":"126388","dateCreated":"1587570776","dateModified":"1587570776"},{"type":"accept","author":"Alphare","id":"114426","dateCreated":"1578045432","dateModified":"1578045432"},{"type":"update","diffId":"18930","author":"gracinet","id":"113731","dateCreated":"1577195430","dateModified":"1577195430"}],"dateCreated":"1577195430","dateModified":"1587570776","status":"Needs Revision"},{"id":"8352","callsign":"HG","title":"extensions: don't crash if __file__ not defined","author":"indygreg","summary":"This attribute isn't present in PyOxidizer when loading modules\nfrom memory.\n\nBefore, this code was crashing under PyOxidizer. After, it simply\nyields unexpected results. This still isn't great (we need a better\nmechanism to discover extensions when modules aren't loaded from\nthe filesystem). But it is strictly better since we no longer\nget tracebacks.","testPlan":"","lineCount":"4","dependsOn":[],"reviewers":["marmoute"],"ccs":["marmoute","mercurial-devel"],"actions":[{"type":"inline","comment":"Maybe mention that the result if \"wrong\" here? If I understand you commit message fine, this change does not make this code work as expected. It only prevent a crash. If I got this right, it would be useful to mention it in the comment.","replyTo":null,"isNewFile":"1","line":"709","lineLength":"0","path":"mercurial\/extensions.py","diffId":"20927","author":"marmoute","id":"124721","dateCreated":"1585729041","dateModified":"1585729041"},{"type":"reject","author":"marmoute","id":"124720","dateCreated":"1585729041","dateModified":"1585729041"},{"type":"update","diffId":"20927","author":"indygreg","id":"124704","dateCreated":"1585711761","dateModified":"1585711761"}],"dateCreated":"1585711761","dateModified":"1585729041","status":"Needs Revision"},{"id":"7967","callsign":"HG","title":"exchange: recognize changegroup3 bundles in `getbundlespec()`","author":"mharbison72","summary":"Previously, `hg bundle --spec $bundle` complained that changegroup3 didn't have\na known bundlespec and suggested upgrading the client, even if the same binary\ngenerated the bundle.","testPlan":"","lineCount":"28","dependsOn":[],"reviewers":["marmoute"],"ccs":["indygreg","marmoute","pulkit","joerg.sonnenberger","mercurial-devel"],"actions":[{"type":"comment","comment":"It looks like futher change will be necessary on this patch, moving it out of yadaa","author":"marmoute","id":"124082","dateCreated":"1584668017","dateModified":"1584668017"},{"type":"reject","author":"marmoute","id":"124081","dateCreated":"1584668017","dateModified":"1584668017"},{"type":"inline","comment":"> That being said, for purposes of parsing a bundle, it _might_ be acceptable to allow experimental\n> features through. We absolutely cannot do that on the write side, however, as it completely breaks\n> the bundle spec contract that content is well-defined.\n\nThat's concerning (I think).\n\nI got onto this path trying to generate clonebundles for a repo that uses LFS. LFS forces the experimental changegroup3 (and removes the others as options). I was able to generate the bundle, and was using this to try to figure out what the magic string was for filling out the manifest. So there are bundles of a not-reported spec in the wild (I assume this is what you meant by the write side). And if we were to BC changegroup3 for example, IDK how we tell that these older bundles are *not* whatever the new bundlespec becomes, since it seems that the only additional needed logic is to look for changegroup3.\n","replyTo":"121577","isNewFile":"1","line":"321","lineLength":"0","path":"mercurial\/exchange.py","diffId":"19502","author":"mharbison72","id":"121579","dateCreated":"1582777785","dateModified":"1582777785"},{"type":"inline","comment":"Since changegroup `v3` is not advertised in an existing bundle spec definition at the top of this file, the proper thing to do here is create a new `v3` bundle specification that uses changegroup v3 by default. Then all bundle spec `v3` will be compatible with changegroup `v3`.\n\nBut before we create a new bundle spec, all features within it need to be non-experimental. The whole point of bundle specs is that if 2 clients of different versions claim they support a bundle spec, they actually do. If the content of a bundle change within a bundle spec, that's a BC.\n\nIf changegroup `v3` isn't stable yet, we should not be associating it with a bundle spec because a claimed `v2` bundle spec may not be readable by an old version or a client without the experimental feature enabled. That breaks the contract of bundle specifications.\n\nThat being said, for purposes of parsing a bundle, it _might_ be acceptable to allow experimental features through. We absolutely cannot do that on the write side, however, as it completely breaks the bundle spec contract that content is well-defined.","replyTo":"117057","isNewFile":"1","line":"321","lineLength":"0","path":"mercurial\/exchange.py","diffId":"19502","author":"indygreg","id":"121577","dateCreated":"1582760232","dateModified":"1582760232"},{"type":"comment","comment":"To clarify, bundle specifications are user-facing whereas changegroup versions are an internal implementation detail. Their version numbers are thus on different timelines and aren't strictly related.\n\nA bundle specification version is essentially a collection of related bundle features at a given point in time. One of those bundle features would be the changegroup version. The idea is that every time we add a significant feature to bundles and want to expose that feature to users, we would bake a new bundle specification version that encapsulates that change. Over time, I would expect the total number of bundle specification versions to outnumber the changegroup versions, as any BC change to a bundle would incur a new bundle specification and there are more changes to bundles than just the changegroup format.\n\nWhile I'm here, in the context of bundle2, a monolithic changegroup bundle part doesn't make as much sense any more. We should arguably do away with the monolithic changegroup bundle2 part and instead send a series of deltas to named paths. But that's way beyond the scope of this review :)","author":"indygreg","id":"121576","dateCreated":"1582759818","dateModified":"1582759818"},{"type":"comment","comment":"It seems like I faild to have a look soon\u2122","author":"marmoute","id":"121561","dateCreated":"1582746860","dateModified":"1582746860"},{"type":"comment","comment":">>! In D7967#118158, @marmoute wrote:\n> I can confirm the spec version number are different to the changegroup version number. For the rest. I'll try to have a look soon.\n\nGentle ping on this","author":"mharbison72","id":"121559","dateCreated":"1582746790","dateModified":"1582746790"},{"type":"comment","comment":"I can confirm the spec version number are different to the changegroup version number. For the rest. I'll try to have a look soon.","author":"marmoute","id":"118158","dateCreated":"1580119112","dateModified":"1580119112"},{"type":"inline","comment":"I\u2019m not sure now. I think I went this way because I\u2019m pretty sure it complained when I tried to generate a bzip2-v3 bundle. And since 01 is mapped to v2 and the error message is talking about finding a bundlespec, it seemed like v2 was the only option. But maybe something is missing elsewhere too. @marmoute?","replyTo":"117054","isNewFile":"1","line":"321","lineLength":"0","path":"mercurial\/exchange.py","diffId":"19502","author":"mharbison72","id":"117057","dateCreated":"1579698258","dateModified":"1579698258"},{"type":"inline","comment":"Should not this be `v3`? I believe this is what @joerg.sonnenberger is also trying to point out on IRC.","replyTo":null,"isNewFile":"1","line":"321","lineLength":"0","path":"mercurial\/exchange.py","diffId":"19502","author":"pulkit","id":"117054","dateCreated":"1579697239","dateModified":"1579697239"},{"type":"update","diffId":"19502","author":"mharbison72","id":"117047","dateCreated":"1579649502","dateModified":"1579649502"}],"dateCreated":"1579649502","dateModified":"1584668017","status":"Needs Revision"},{"id":"8290","callsign":"HG","title":"morestatus: recommend `hg resolve --clear` when appropriate","author":"martinvonz","summary":"","testPlan":"","lineCount":"5","dependsOn":["8289"],"reviewers":["marmoute"],"ccs":["marmoute","mercurial-devel"],"actions":[{"type":"comment","comment":"This on seems need to be updated with `hg update --continue\/hg continue`","author":"marmoute","id":"124073","dateCreated":"1584662533","dateModified":"1584662533"},{"type":"reject","author":"marmoute","id":"124072","dateCreated":"1584662533","dateModified":"1584662533"},{"type":"update","diffId":"20779","author":"martinvonz","id":"123736","dateCreated":"1584134456","dateModified":"1584134456"}],"dateCreated":"1584134456","dateModified":"1584662533","status":"Needs Revision"},{"id":"8289","callsign":"HG","title":"resolve: add a --clear option for clearing the merge state","author":"martinvonz","summary":"E.g. after running `hg co -m` and resolving merge conflicts, the merge\nstate will still exist. That can be seen when running `hg resolve -l`\nor `hg status -v` (a.k.a. morestatus). There's currently no good way\nof clearing it (`hg co -C .` works, but is not an option if you have a\ndirty working copy). This patch adds `hg resolve --clear` specifically\nfor clearing the merge state.","testPlan":"","lineCount":"57","dependsOn":[],"reviewers":[],"ccs":["marmoute","pulkit","mercurial-devel"],"actions":[{"type":"comment","comment":">>! In D8289#124060, @marmoute wrote:\n>>>! In D8289#124009, @pulkit wrote:\n>> I like the idea. IIRC, Ryan from FB hit similar issues in a sprint some years ago and came up with `hg up --finish` or something like that.\n>> \n>> Maybe we should not let user clear the mergestate and suggest `continue\/<cmd-name> --continue` if it's not result of update command. Thoughts?\n> \n> Ho, that's a good idea. It looks like `hg update --merge` is the only command that do not have `--continue` support. So instead of adding a whole new flag and action to this exception, removing the exception seems like a better move. What do you think @martinvonz ?\n\nYeah, I agree (sorry, was busy with other stuff today). It should be easy to change this patch from `hg resolve --clear` to `hg update --continue`. I might add the `hg continue` support as separate patch on top.","author":"martinvonz","id":"124062","dateCreated":"1584662143","dateModified":"1584662143"},{"type":"plan-changes","author":"martinvonz","id":"124061","dateCreated":"1584662143","dateModified":"1584662143"},{"type":"comment","comment":">>! In D8289#124009, @pulkit wrote:\n> I like the idea. IIRC, Ryan from FB hit similar issues in a sprint some years ago and came up with `hg up --finish` or something like that.\n> \n> Maybe we should not let user clear the mergestate and suggest `continue\/<cmd-name> --continue` if it's not result of update command. Thoughts?\n\nHo, that's a good idea. It looks like `hg update --merge` is the only command that do not have `--continue` support. So instead of adding a whole new flag and action to this exception, removing the exception seems like a better move. What do you think @martinvonz ?","author":"marmoute","id":"124060","dateCreated":"1584661388","dateModified":"1584661388"},{"type":"comment","comment":"I like the idea. IIRC, Ryan from FB hit similar issues in a sprint some years ago and came up with `hg up --finish` or something like that.\n\nMaybe we should not let user clear the mergestate and suggest `continue\/<cmd-name> --continue` if it's not result of update command. Thoughts?","author":"pulkit","id":"124009","dateCreated":"1584606645","dateModified":"1584606645"},{"type":"update","diffId":"20820","author":"martinvonz","id":"123959","dateCreated":"1584482717","dateModified":"1584482717"},{"type":"update","diffId":"20778","author":"martinvonz","id":"123731","dateCreated":"1584134455","dateModified":"1584134455"}],"dateCreated":"1584134455","dateModified":"1584662143","status":"Changes Planned"},{"id":"7574","callsign":"HG","title":"hg-core: add utils::path to project","author":"indygreg","summary":"This module was vendored in the previous commit but was not integrated into\nthe project. This commit performs that integration.\n\nAs part of this, we have to add a handful of new dependencies. The new\ndependencies all seem quite reasonable. The versions taken were the exact\nones used by the upstream project.","testPlan":"","lineCount":"309","dependsOn":[],"reviewers":["pulkit","marmoute"],"ccs":["marmoute","Alphare","durin42","kevincox","mercurial-devel"],"actions":[{"type":"comment","comment":"Looks like there are unresolved discussion about error handling here.","author":"marmoute","id":"124048","dateCreated":"1584659079","dateModified":"1584659079"},{"type":"reject","author":"marmoute","id":"124047","dateCreated":"1584659079","dateModified":"1584659079"},{"type":"comment","comment":"This one fails to apply with conflicts in `Cargo.lock`.","author":"pulkit","id":"115314","dateCreated":"1578933699","dateModified":"1578933699"},{"type":"reject","author":"pulkit","id":"115313","dateCreated":"1578933699","dateModified":"1578933699"},{"type":"accept","author":"pulkit","id":"115309","dateCreated":"1578933323","dateModified":"1578933323"},{"type":"inline","comment":"I actually wasn't aware of `anyhow` before writing this patch. And I have to say that I really like `anyhow` because it is simpler than other crates in this space while offering much of the same functionality.\n\nI think it is inevitable that we'll want to use a crate like `anyhow` for more advanced error handling. If nothing else, it can help cut down on boilerplate code around error handling.","replyTo":"111442","isNewFile":"1","line":"12","lineLength":"0","path":"rust\/hg-core\/Cargo.toml","diffId":"18534","author":"indygreg","id":"113657","dateCreated":"1577124884","dateModified":"1577124884"},{"type":"inline","comment":"Should we adopt this crate for error handling?\n\nI feel like our current solution - although it might need a refactor - is good at forcing the programmer to provide context with finer-grained errors that what you are required to do with `anyhow`. I actually like `anyhow` better than more involved crates, but we will need to have a good \"error hygiene\" if you will.\n\nThis seems like a better place to discuss this than the previous patch.","replyTo":null,"isNewFile":"1","line":"12","lineLength":"0","path":"rust\/hg-core\/Cargo.toml","diffId":"18534","author":"Alphare","id":"111442","dateCreated":"1575888850","dateModified":"1575888850"},{"type":"update","diffId":"18534","author":"indygreg","id":"111325","dateCreated":"1575749869","dateModified":"1575749869"}],"dateCreated":"1575749869","dateModified":"1584659079","status":"Needs Revision"},{"id":"8227","callsign":"HG","title":"hgit: use type_str instead of type for checking type of git objects","author":"pulkit","summary":"type returns a constant which were integers.\n\nhttps:\/\/www.pygit2.org\/objects.html#pygit2.Object.type","testPlan":"","lineCount":"2","dependsOn":[],"reviewers":[],"ccs":["mercurial-devel"],"actions":[{"type":"comment","comment":"I should add some tests.","author":"pulkit","id":"122409","dateCreated":"1583420586","dateModified":"1583420586"},{"type":"plan-changes","author":"pulkit","id":"122408","dateCreated":"1583420586","dateModified":"1583420586"},{"type":"update","diffId":"20506","author":"pulkit","id":"122405","dateCreated":"1583419454","dateModified":"1583419454"},{"type":"update","diffId":"20505","author":"pulkit","id":"122400","dateCreated":"1583419181","dateModified":"1583419181"}],"dateCreated":"1583419181","dateModified":"1583420586","status":"Changes Planned"},{"id":"7257","callsign":"HG","title":"[RFC] repoview: add a \"filter\" that just disallows walking to heads","author":"martinvonz","summary":"This can let us find bugs where we think it shouldn't matter whether\nwe're using an unfiltered or filtered repo. We could then get a repo\nthat is using this new \"filter\" and if the code ends up trying to walk\nthe graph towards the changelog children, we would notice that.","testPlan":"","lineCount":"30","dependsOn":[],"reviewers":["durin42","baymax"],"ccs":["durin42","marmoute","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"121134","dateCreated":"1582275051","dateModified":"1582275051"},{"type":"reject","author":"baymax","id":"121133","dateCreated":"1582275051","dateModified":"1582275051"},{"type":"comment","comment":"I'm a big fan of this idea. I'd probably land it if there were some obvious usecases as child patches. :)","author":"durin42","id":"108443","dateCreated":"1573686616","dateModified":"1573686616"},{"type":"accept","author":"durin42","id":"108442","dateCreated":"1573686616","dateModified":"1573686616"},{"type":"comment","comment":">>! In D7257#108377, @marmoute wrote:\n> Can you elaborate on what this changeset is about ? the description is a bit\u2026 short;-)\n\nDone.","author":"martinvonz","id":"108379","dateCreated":"1573597314","dateModified":"1573597314"},{"type":"comment","comment":"Can you elaborate on what this changeset is about ? the description is a bit\u2026 short;-)","author":"marmoute","id":"108377","dateCreated":"1573596371","dateModified":"1573596371"},{"type":"update","diffId":"18048","author":"martinvonz","id":"108373","dateCreated":"1573594402","dateModified":"1573594402"},{"type":"update","diffId":"17625","author":"martinvonz","id":"106360","dateCreated":"1573059703","dateModified":"1573059703"}],"dateCreated":"1573059703","dateModified":"1582275051","status":"Needs Revision"},{"id":"7728","callsign":"HG","title":"rebase: add test to demonstrate issue6180","author":"khanchi97","summary":"It will be fixed in next patch.","testPlan":"","lineCount":"63","dependsOn":[],"reviewers":["marmoute"],"ccs":["marmoute","pulkit","mercurial-devel"],"actions":[{"type":"comment","comment":"As per comment of Pulkit and I on D7730, please spin this test toward forbiding the prune while the rebase is in progress.","author":"marmoute","id":"120855","dateCreated":"1581669482","dateModified":"1581669482"},{"type":"reject","author":"marmoute","id":"120854","dateCreated":"1581669482","dateModified":"1581669482"},{"type":"comment","comment":"Cf my comment on D7730, I think the bug is more about letting others commands obsoleting things happens (eg, amend, pull, etc) than rebase being confused by the result.","author":"marmoute","id":"119015","dateCreated":"1580600761","dateModified":"1580600761"},{"type":"update","diffId":"19815","author":"khanchi97","id":"119011","dateCreated":"1580582406","dateModified":"1580582406"},{"type":"update","diffId":"19282","author":"khanchi97","id":"115765","dateCreated":"1579084940","dateModified":"1579084940"},{"type":"inline","comment":"You don't need to redefine it.","replyTo":null,"isNewFile":"1","line":"438","lineLength":"0","path":"tests\/test-rebase-conflicts.t","diffId":"18937","author":"pulkit","id":"114951","dateCreated":"1578579588","dateModified":"1578579588"},{"type":"comment","comment":"Ping.","author":"khanchi97","id":"114662","dateCreated":"1578483193","dateModified":"1578483193"},{"type":"update","diffId":"18937","author":"khanchi97","id":"113781","dateCreated":"1577465814","dateModified":"1577465814"}],"dateCreated":"1577465814","dateModified":"1581669482","status":"Needs Revision"},{"id":"7730","callsign":"HG","title":"rebase: make sure pruning does not confuse rebase (issue6180)","author":"khanchi97","summary":"Before this patch, if a user is rebasing a stack of commits and\nhit a conflict in between and decided to drop that commit (the commit\nwhich is being rebased but hit conflict) and pruned it, now what\n`hg rebase --continue` does is: skip that dropped commit and move\non to rebase the next commit and gets confused here because wdir\nhas two parents which is because while we skipped that dropped\ncommit wdir had two parents and we didn't update that to one parent.\n\nChanges in test file demonstrate the fixed behavior.","testPlan":"","lineCount":"11","dependsOn":["7728"],"reviewers":["martinvonz","marmoute"],"ccs":["marmoute","pulkit","mercurial-devel"],"actions":[{"type":"comment","comment":">>! In D7730#119191, @pulkit wrote:\n>>>! In D7730#117268, @marmoute wrote:\n>> I think is would be simpler and sfare to prevent unrelated operation during rebase. If the user cannot prune here we won't have to deal with it. This woudl also apply to other operation that can alter the repository, like another rebase, amend or a pull. Starting using a unified and safe approach seems to provide more benefit with less chance of UI inconsistency.\n> \n> I agree. We should disallow prune if an unfinished operation exists.\n\nOkay, lets to in this direction then.","author":"marmoute","id":"120852","dateCreated":"1581668628","dateModified":"1581668628"},{"type":"reject","author":"marmoute","id":"120851","dateCreated":"1581668628","dateModified":"1581668628"},{"type":"comment","comment":">>! In D7730#117268, @marmoute wrote:\n> I think is would be simpler and sfare to prevent unrelated operation during rebase. If the user cannot prune here we won't have to deal with it. This woudl also apply to other operation that can alter the repository, like another rebase, amend or a pull. Starting using a unified and safe approach seems to provide more benefit with less chance of UI inconsistency.\n\nI agree. We should disallow prune if an unfinished operation exists.","author":"pulkit","id":"119191","dateCreated":"1580815575","dateModified":"1580815575"},{"type":"update","diffId":"19816","author":"khanchi97","id":"119012","dateCreated":"1580582417","dateModified":"1580582417"},{"type":"comment","comment":"I think is would be simpler and sfare to prevent unrelated operation during rebase. If the user cannot prune here we won't have to deal with it. This woudl also apply to other operation that can alter the repository, like another rebase, amend or a pull. Starting using a unified and safe approach seems to provide more benefit with less chance of UI inconsistency.","author":"marmoute","id":"117268","dateCreated":"1579797320","dateModified":"1579797320"},{"type":"inline","comment":"Actually, doesn't this need to be `wctx.setparents()` (which you can do now that D7822 has been queued) in order to work with in-memory rebase? Maybe time to add a test case with in-memory rebase?","replyTo":null,"isNewFile":"1","line":"600","lineLength":"0","path":"hgext\/rebase.py","diffId":"19283","author":"martinvonz","id":"115947","dateCreated":"1579106322","dateModified":"1579106322"},{"type":"inline","comment":"No need, I've already sent D7827","replyTo":"115783","isNewFile":"1","line":"597","lineLength":"0","path":"hgext\/rebase.py","diffId":"18939","author":"martinvonz","id":"115944","dateCreated":"1579106125","dateModified":"1579106125"},{"type":"inline","comment":"I will look into it.","replyTo":"114713","isNewFile":"1","line":"597","lineLength":"0","path":"hgext\/rebase.py","diffId":"18939","author":"khanchi97","id":"115783","dateCreated":"1579093511","dateModified":"1579093511"},{"type":"comment","comment":">>! In D7730#114953, @pulkit wrote:\n> Unrelated to the fix, we need better way to skip commits during rebasing. Pruning manually is not a good option, IIRC git rebase have a `--skip` flag.\n\nYeah, that's a good idea. We should also have --skip flag to skip the commit on which rebase got interrupted.","author":"khanchi97","id":"115781","dateCreated":"1579093387","dateModified":"1579093387"},{"type":"update","diffId":"19283","author":"khanchi97","id":"115766","dateCreated":"1579084952","dateModified":"1579084952"},{"type":"comment","comment":"Unrelated to the fix, we need better way to skip commits during rebasing. Pruning manually is not a good option, IIRC git rebase have a `--skip` flag.","author":"pulkit","id":"114953","dateCreated":"1578579692","dateModified":"1578579692"},{"type":"inline","comment":"I think it's incorrect that rebase sets two parents while the merge is being resolved, but that's out of scope for this patch.","replyTo":null,"isNewFile":"1","line":"597","lineLength":"0","path":"hgext\/rebase.py","diffId":"18939","author":"martinvonz","id":"114713","dateCreated":"1578505063","dateModified":"1578505063"},{"type":"inline","comment":"Should this be `self.wctx.parents()` to work with in-memory rebase?","replyTo":null,"isNewFile":"1","line":"598","lineLength":"0","path":"hgext\/rebase.py","diffId":"18939","author":"martinvonz","id":"114712","dateCreated":"1578505063","dateModified":"1578505063"},{"type":"comment","comment":"Ping.","author":"khanchi97","id":"114663","dateCreated":"1578483218","dateModified":"1578483218"},{"type":"update","diffId":"18939","author":"khanchi97","id":"113800","dateCreated":"1577466343","dateModified":"1577466343"}],"dateCreated":"1577466343","dateModified":"1581668628","status":"Needs Revision"},{"id":"7942","callsign":"HG","title":"py3: make test-http-bad-server.t conditional on Python 3.6+","author":"indygreg","summary":"I'm not sure what's going on here, but we need to limit these lines\nto a Python 3.6 version range check because Python 3.5's behavior\nis subtly different. We already had some lines conditional on\nPython 3.5+ and 3.6+. I guess whoever made this test pass on 3.6+\nforgot to test on 3.5+.\n\nWith this change, the test harness is clean on Python 3.5 on Linux\non my machine.","testPlan":"","lineCount":"10","dependsOn":["7941"],"reviewers":["pulkit","marmoute"],"ccs":["mjpieters","mercurial-devel"],"actions":[{"type":"accept","author":"marmoute","id":"119441","dateCreated":"1580944098","dateModified":"1580944098"},{"type":"accept","author":"pulkit","id":"116764","dateCreated":"1579528946","dateModified":"1579528946"},{"type":"update","diffId":"19446","author":"indygreg","id":"116676","dateCreated":"1579333363","dateModified":"1579333363"}],"dateCreated":"1579333363","dateModified":"1580944098","status":"Accepted"},{"id":"7940","callsign":"HG","title":"py3: make flush() line optional","author":"indygreg","summary":"This line only appears on Python 3.5, not on 2.7 or 3.6+. Why, I have\nno clue. I suspect a weird regression in the bowels of Python's\nI\/O system.\n\nOur test format doesn't support combining conditionals. So I add\npyexactXY checks to check for an exact major.minor Python version.\nSadly, this won't be the only test requiring an exception for\nPython 3.5.","testPlan":"","lineCount":"12","dependsOn":[],"reviewers":["pulkit","marmoute"],"ccs":["marmoute","mercurial-devel"],"actions":[{"type":"inline","comment":"\n+1 are we missing anything that prevent this to be used?","replyTo":"116766","isNewFile":"1","line":"114","lineLength":"0","path":"tests\/test-ssh-proto.t","diffId":"19444","author":"marmoute","id":"119439","dateCreated":"1580943965","dateModified":"1580943965"},{"type":"inline","comment":"can we pre-generate more python version ? It help running \"current\" extension test againts \"older\" mercurial version.","replyTo":null,"isNewFile":"1","line":"783","lineLength":"0","path":"tests\/hghave.py","diffId":"19444","author":"marmoute","id":"119438","dateCreated":"1580943965","dateModified":"1580943965"},{"type":"reject","author":"marmoute","id":"119437","dateCreated":"1580943965","dateModified":"1580943965"},{"type":"inline","comment":"Reviewing later patches, I see that `(py3 no-py3.6)` can be used for this.","replyTo":null,"isNewFile":"1","line":"114","lineLength":"0","path":"tests\/test-ssh-proto.t","diffId":"19444","author":"pulkit","id":"116766","dateCreated":"1579529000","dateModified":"1579529000"},{"type":"accept","author":"pulkit","id":"116758","dateCreated":"1579528720","dateModified":"1579528720"},{"type":"update","diffId":"19444","author":"indygreg","id":"116660","dateCreated":"1579333360","dateModified":"1579333360"}],"dateCreated":"1579333360","dateModified":"1580943966","status":"Needs Revision"},{"id":"7176","callsign":"HG","title":"rebase: allow rebasing obsolete commit without successor","author":"martinvonz","summary":"When trying to rebase an obsolete whose successors are also all\nobsolete, we would skip it and tell the user that it would have caused\ndivergence. That is not correct. We could just change the message, but\nI don't see any harm in rebasing such commits. It even seems like a\nreasonable way to make it not obsolete. So this patch makes that type\nof rebase allowed.","testPlan":"","lineCount":"9","dependsOn":["7175"],"reviewers":["baymax"],"ccs":["marmoute","khanchi97","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"118730","dateCreated":"1580407580","dateModified":"1580407580"},{"type":"reject","author":"baymax","id":"118729","dateCreated":"1580407580","dateModified":"1580407580"},{"type":"comment","comment":"That is not necessarly True, If the changeset is pruned, but successors of a public changeset, rebasing it would create phase-divergence. @khanchi97 fixed similar cases in September.\n\nOverall, we should migrate the rebase code to use the `precheck` logic in rewrite util (and make sure things are well covered there).\n\nOne can read more about current Sushil work in this area here: https:\/\/www.mercurial-scm.org\/wiki\/CEDPrecheckPlan.","author":"marmoute","id":"105351","dateCreated":"1572465579","dateModified":"1572465579"},{"type":"update","diffId":"17409","author":"martinvonz","id":"105299","dateCreated":"1572050933","dateModified":"1572050933"}],"dateCreated":"1572050933","dateModified":"1580407580","status":"Needs Revision"},{"id":"3896","callsign":"HG","title":"copies: handle case when both merge cset are not descendant of merge base","author":"pulkit","summary":"There can be cases when both the changesets which we are merging are not\ndescendants of the merge base. In those cases dirtyc1 and dirtyc2 both will be\ntrue. The existing code assumes that either of them will be true always but that\nis not a right assumption.\n\nI found this while working with content-divergence resolution. In\ncontent-divergence resolution, we use the common predecessor as the merge base\nfor resolving content divergence and there it can be possible that the merge\nbase is not the descendant of both the content-divergence changsets.\n\nThe code in content-divergence which does this is at:\nhttps:\/\/www.mercurial-scm.org\/repo\/evolve\/file\/b81fd1487e04\/hgext3rd\/evolve\/evolvecmd.py#l507","testPlan":"","lineCount":"5","dependsOn":[],"reviewers":["baymax"],"ccs":["martinvonz","spectral","yuja","mercurial-devel"],"actions":[{"type":"comment","comment":"Pretty sure this was made obsolete by D6255","author":"martinvonz","id":"118457","dateCreated":"1580315479","dateModified":"1580315479"},{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117663","dateCreated":"1579887172","dateModified":"1579887172"},{"type":"reject","author":"baymax","id":"117662","dateCreated":"1579887172","dateModified":"1579887172"},{"type":"comment","comment":">>! In D3896#65986, @spectral wrote:\n> Any updates on this? I'm poking at updating this function in core, and not too excited to have to also modify the copy in evolve that seems to have spawned :\/\n\nI am yet to write tests. Feel free to update the one in core, I will take care of the evolve copy.","author":"pulkit","id":"66180","dateCreated":"1534428512","dateModified":"1534428512"},{"type":"comment","comment":"Any updates on this? I'm poking at updating this function in core, and not too excited to have to also modify the copy in evolve that seems to have spawned :\/","author":"spectral","id":"65987","dateCreated":"1534370496","dateModified":"1534370496"},{"type":"comment","comment":"Can you add some tests that make both `dirtyc1` and `dirtyc2` set, and\ntrigger copy tracing?\n\n> Since we can have both dirtyc1, and dirtyc2 true, I am not sure whether\n> this else should be turned into it's own if statement?\n\nNo idea. I doubt if the current copy tracing can handle such cases. From\nmy vague memory, the current algorithm relies on the fact that the pseudo\n`base` revision exists in between the `c1` and the `c2`.","author":"yuja","id":"60811","dateCreated":"1531138991","dateModified":"1531138991"},{"type":"inline","comment":"Since we can have both dirtyc1, and dirtyc2 true, I am not sure whether this else should be turned into it's own if statement?","replyTo":null,"isNewFile":"1","line":"496","lineLength":"0","path":"mercurial\/copies.py","diffId":"9471","author":"pulkit","id":"60802","dateCreated":"1531041256","dateModified":"1531041256"},{"type":"update","diffId":"9471","author":"pulkit","id":"60797","dateCreated":"1531041116","dateModified":"1531041116"}],"dateCreated":"1531041116","dateModified":"1580315479","status":"Needs Revision"},{"id":"1700","callsign":"HG","title":"logtoprocess: pass ui in runshellcommand","author":"lothiraldan","summary":"We are gonna read a configuration specific to Windows, instead of adding a\nuseless arguments for runshellcommand on linux, pass the ui object to read it\ndirectly.","testPlan":"","lineCount":"6","dependsOn":[],"reviewers":["baymax"],"ccs":["mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117739","dateCreated":"1579887208","dateModified":"1579887208"},{"type":"reject","author":"baymax","id":"117738","dateCreated":"1579887208","dateModified":"1579887208"},{"type":"update","diffId":"4467","author":"lothiraldan","id":"29023","dateCreated":"1513332655","dateModified":"1513332655"}],"dateCreated":"1513332655","dateModified":"1579887208","status":"Needs Revision"},{"id":"1752","callsign":"HG","title":"tests: show phases aren't preserved part of streaming clone (issue5648)","author":"indygreg","summary":"draft and secret changesets are promoted to public changesets when\ntransferred via a stream clone. That's not desirable behavior. Add\ntests demonstrating it.\n\nAs far as I can tell, this buggy behavior has been present since\nphases were introduced. Stream clone predated phases (1.7 versus 1.9)\nand stream clone was never taught to be phase aware.","testPlan":"","lineCount":"65","dependsOn":[],"reviewers":["baymax"],"ccs":["mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117733","dateCreated":"1579887204","dateModified":"1579887204"},{"type":"reject","author":"baymax","id":"117732","dateCreated":"1579887204","dateModified":"1579887204"},{"type":"update","diffId":"4602","author":"indygreg","id":"29880","dateCreated":"1514138808","dateModified":"1514138808"}],"dateCreated":"1514138808","dateModified":"1579887205","status":"Needs Revision"},{"id":"1765","callsign":"HG","title":"parsers: use an attr-derived class for revlog index entries","author":"indygreg","summary":"Currently, revlog index entries are tuples.\n\nThis commit introduces a new type to represent revlog v1 index\nentries. The pure Python parser has been converted to use it.\n\nTo provide backwards compatibility with existing code (including the\nC extension), the type has a __getitem__ to facilitate index\nlookups. The intent is to remove this __getitem__ once all consumers\nare using named attributes.\n\nSince the pure Python index parser is now using our new type,\ntest-parseindex2.py had to be updated to deal with the type mismatch.\nOnce all index parsers are converted and the new type\/interface is\nubiquitous, we can restore the simplicity of test-parseindex2.py. We\nalso had to (temporarily) add \"# no-check-code\" to test-parseindex2.py\nto allow the import of the pure module. This will be removed once the C\nextension is ported.\n\nBecause consumers are going through an extra Python function call to\n__getitem__ to resolve attributes by index, this change regresses\nperformance on a simple DAG walking revset for the Firefox repository:\n\n$ HGMODULEPOLICY=py hg perfrevset '::tip'\n! wall 1.366281 comb 1.360000 user 1.360000 sys 0.000000 (best of 7)\n! wall 1.860068 comb 1.860000 user 1.860000 sys 0.000000 (best of 5)\n\nUsing PyPy, a major regression is not apparent:\n\n! wall 0.163141 comb 0.160000 user 0.160000 sys 0.000000 (best of 56)\n! wall 0.154325 comb 0.160000 user 0.160000 sys 0.000000 (best of 54)","testPlan":"","lineCount":"70","dependsOn":[],"reviewers":["yuja","durin42","baymax"],"ccs":["yuja","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117730","dateCreated":"1579887202","dateModified":"1579887202"},{"type":"reject","author":"baymax","id":"117729","dateCreated":"1579887202","dateModified":"1579887202"},{"type":"accept","author":"durin42","id":"31062","dateCreated":"1515624886","dateModified":"1515624886"},{"type":"update","diffId":"4735","author":"indygreg","id":"30856","dateCreated":"1515227175","dateModified":"1515227175"},{"type":"inline","comment":"Perhaps you mean `list(map(...))` instead of a list of one element?","replyTo":null,"isNewFile":"1","line":"182","lineLength":"0","path":"tests\/test-parseindex2.py","diffId":"4626","author":"yuja","id":"30602","dateCreated":"1515124211","dateModified":"1515124211"},{"type":"reject","author":"yuja","id":"30601","dateCreated":"1515124211","dateModified":"1515124211"},{"type":"update","diffId":"4626","author":"indygreg","id":"30049","dateCreated":"1514334949","dateModified":"1514334949"}],"dateCreated":"1514334949","dateModified":"1579887202","status":"Needs Revision"},{"id":"1767","callsign":"HG","title":"cext: make nullentry a member of index types","author":"indygreg","summary":"An upcoming commit will change the type of index entries from tuple\nto something else. This type may not be initialized\/available at\nmodule init time.\n\nWe prepare for this future change by making null entries a per-instance\nvariable on the index type.\n\nIn theory, this does add some overhead (a new 8-tuple per index\ninstance). However, the overhead should be negligible compared to\nthe run-time overhead of creating an index entry for each revision\nin the index.","testPlan":"","lineCount":"19","dependsOn":["1766"],"reviewers":["yuja","durin42","baymax"],"ccs":["yuja","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117727","dateCreated":"1579887200","dateModified":"1579887200"},{"type":"reject","author":"baymax","id":"117726","dateCreated":"1579887200","dateModified":"1579887200"},{"type":"accept","author":"durin42","id":"31065","dateCreated":"1515624888","dateModified":"1515624888"},{"type":"update","diffId":"4736","author":"indygreg","id":"30859","dateCreated":"1515227176","dateModified":"1515227176"},{"type":"inline","comment":"This comment shouldn't be moved. We need to NULLify all attributes, but don't\nhave to create PyObject.","replyTo":null,"isNewFile":"1","line":"1876","lineLength":"0","path":"mercurial\/cext\/revlog.c","diffId":"4628","author":"yuja","id":"30606","dateCreated":"1515124415","dateModified":"1515124415"},{"type":"reject","author":"yuja","id":"30605","dateCreated":"1515124415","dateModified":"1515124415"},{"type":"update","diffId":"4628","author":"indygreg","id":"30069","dateCreated":"1514334953","dateModified":"1514334953"}],"dateCreated":"1514334953","dateModified":"1579887200","status":"Needs Revision"},{"id":"1768","callsign":"HG","title":"cext: obtain reference to index entry type","author":"indygreg","summary":"We recently introduced a dedicated type for index entries in the\npure Python implementation.\n\nThis commit tells the revlog C code about that type.\n\nWe register the type on the parsers module so it is exposed to\nimporters of the module.\n\nIn addition, we store a reference to the type on revlog index\ninstances. In theory, we could grab the reference from the\nmodule. However, this requires a fair bit of C code. It is easier\nto just re-import the original module and get a ref from there. This\nalso avoids problems with caching a type on a reload()d module.","testPlan":"","lineCount":"35","dependsOn":["1767"],"reviewers":["yuja","durin42","baymax"],"ccs":["yuja","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117724","dateCreated":"1579887199","dateModified":"1579887199"},{"type":"reject","author":"baymax","id":"117723","dateCreated":"1579887199","dateModified":"1579887199"},{"type":"accept","author":"durin42","id":"31066","dateCreated":"1515624888","dateModified":"1515624888"},{"type":"update","diffId":"4737","author":"indygreg","id":"30861","dateCreated":"1515227177","dateModified":"1515227177"},{"type":"inline","comment":"In theory, there could be a mismatch.\n\nIf this module is loaded, its `IndexV1Entry` will refer to whatever `mercurial.pure.parsers.IndexV1Entry` is. If `mercurial.pure.parsers` is then reloaded and its `IndexV1Entry` changes and a revlog index type is created, its `IndexV1Entry` will be the new one from the reloaded `mercurial.pure.parsers`.\n\nSince I plan to replace the Python-implemented type with a C backed type, I'm inclined to not care about this.","replyTo":"30611","isNewFile":"1","line":"2117","lineLength":"0","path":"mercurial\/cext\/revlog.c","diffId":"4629","author":"indygreg","id":"30845","dateCreated":"1515222660","dateModified":"1515222660"},{"type":"inline","comment":"Can we be sure that this `IndexV1Entry` is identical to `self->entrytype`\nafter reloading Python modules?","replyTo":null,"isNewFile":"1","line":"2117","lineLength":"0","path":"mercurial\/cext\/revlog.c","diffId":"4629","author":"yuja","id":"30611","dateCreated":"1515128067","dateModified":"1515128067"},{"type":"comment","comment":"> We hold off incrementing the version of the \"parsers\" extension\n> because nothing in core relies on the new API yet.\n\nIt's really minor nit, but we have to increment the version since new\ncompiled module doesn't work with old `pure.parsers` module, which\nprovides no IndexV1Entry type.","author":"yuja","id":"30610","dateCreated":"1515128067","dateModified":"1515128067"},{"type":"reject","author":"yuja","id":"30609","dateCreated":"1515128067","dateModified":"1515128067"},{"type":"update","diffId":"4629","author":"indygreg","id":"30079","dateCreated":"1514334955","dateModified":"1514334955"}],"dateCreated":"1514334955","dateModified":"1579887199","status":"Needs Revision"},{"id":"1769","callsign":"HG","title":"cext: use dedicated type for index entries","author":"indygreg","summary":"Now that we have a handle on our type to represent revlog index\nentries, let's use it.\n\nThis commit essentially consists of porting code from PyTuple to\nPyObject.\n\nAs part of porting the code, we now retrieve elements in the entry\ntype by named attribute instead of integer index.\n\nBefore, PyTuple_* APIs allowed us to retrieve a borrowed reference\nto PyObject elements. We can no longer do this via the PyObject_*\nAPIs for a type not implemented in C. This required extra refcount\nmanipulation in various places.\n\nThe C extension is now emitting the new type. And because various\ncode is still accessing index entry elements via __getitem__, we\nsee a performance regression in the Firefox repository:\n\n$ hg perfrevset '::tip'\n! wall 0.755869 comb 0.750000 user 0.750000 sys 0.000000 (best of 13)\n! wall 1.011107 comb 1.010000 user 1.010000 sys 0.000000 (best of 10)\n\nWe will claw back this regression in subsequent commits by accessing\nfields by name instead of index.\n\nThe version of the \"parsers\" C extension has been incremented to\nreflect the change in behavior.","testPlan":"","lineCount":"123","dependsOn":["1768"],"reviewers":["yuja","durin42","baymax"],"ccs":["yuja","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117721","dateCreated":"1579887198","dateModified":"1579887198"},{"type":"reject","author":"baymax","id":"117720","dateCreated":"1579887198","dateModified":"1579887198"},{"type":"accept","author":"durin42","id":"31067","dateCreated":"1515624889","dateModified":"1515624889"},{"type":"update","diffId":"4738","author":"indygreg","id":"30864","dateCreated":"1515227178","dateModified":"1515227178"},{"type":"inline","comment":"No error reported to the caller.\n\nAttributeError would be set automatically.","replyTo":null,"isNewFile":"1","line":"1788","lineLength":"0","path":"mercurial\/cext\/revlog.c","diffId":"4630","author":"yuja","id":"30618","dateCreated":"1515129734","dateModified":"1515129734"},{"type":"inline","comment":"I slightly prefer `goto bail` instead of `result = NULL; goto cleanup` pairs.","replyTo":null,"isNewFile":"1","line":"327","lineLength":"0","path":"mercurial\/cext\/revlog.c","diffId":"4630","author":"yuja","id":"30617","dateCreated":"1515129734","dateModified":"1515129734"},{"type":"inline","comment":"This is tricky, but looks okay. Alternatively, we could inc\/decref borrowed `obj`.","replyTo":null,"isNewFile":"1","line":"321","lineLength":"0","path":"mercurial\/cext\/revlog.c","diffId":"4630","author":"yuja","id":"30616","dateCreated":"1515129734","dateModified":"1515129734"},{"type":"inline","comment":"Perhaps AttributeError would be set by `PyObject_GetAttrString()`.","replyTo":null,"isNewFile":"1","line":"141","lineLength":"0","path":"mercurial\/cext\/revlog.c","diffId":"4630","author":"yuja","id":"30615","dateCreated":"1515129734","dateModified":"1515129734"},{"type":"reject","author":"yuja","id":"30614","dateCreated":"1515129734","dateModified":"1515129734"},{"type":"update","diffId":"4630","author":"indygreg","id":"30089","dateCreated":"1514334957","dateModified":"1514334957"}],"dateCreated":"1514334957","dateModified":"1579887198","status":"Needs Revision"},{"id":"2158","callsign":"HG","title":"py3: use raw string for open() mode","author":"indygreg","summary":" ","testPlan":"","lineCount":"8","dependsOn":[],"reviewers":["baymax"],"ccs":["yuja","pulkit","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117718","dateCreated":"1579887197","dateModified":"1579887197"},{"type":"reject","author":"baymax","id":"117717","dateCreated":"1579887196","dateModified":"1579887196"},{"type":"comment","comment":"I wanna leave it with no prefix as possible. I think we'll have to bulk-replace\n`''`s to `b''`s at some point so we can leverage static analysis tools, where\n`r''` will be unneeded.","author":"yuja","id":"35990","dateCreated":"1518432079","dateModified":"1518432079"},{"type":"comment","comment":"Looks like a better approach will be to revert this change: https:\/\/www.mercurial-scm.org\/repo\/hg\/rev\/7c54917b31f6. I did that in favor of pycompat.open() and now I think it's better to revert that change. ","author":"pulkit","id":"35944","dateCreated":"1518420826","dateModified":"1518420826"},{"type":"update","diffId":"5459","author":"indygreg","id":"35745","dateCreated":"1518402936","dateModified":"1518402936"}],"dateCreated":"1518402936","dateModified":"1579887197","status":"Needs Revision"},{"id":"2622","callsign":"HG","title":"ui: adding a generic method to read config items with an arbitrary type","author":"rdamazio","summary":"This can be used for reading many config options of various types where the\ntype of each is known in some other structure (e.g. options matching command\nflags).","testPlan":"","lineCount":"10","dependsOn":[],"reviewers":["baymax"],"ccs":["mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117715","dateCreated":"1579887195","dateModified":"1579887195"},{"type":"reject","author":"baymax","id":"117714","dateCreated":"1579887195","dateModified":"1579887195"},{"type":"update","diffId":"6520","author":"rdamazio","id":"42415","dateCreated":"1520121279","dateModified":"1520121279"}],"dateCreated":"1520121279","dateModified":"1579887195","status":"Needs Revision"},{"id":"2680","callsign":"HG","title":"[PoC] obsolete: make markers database writable if local-only mode enabled","author":"indygreg","summary":" ","testPlan":"","lineCount":"4","dependsOn":["2679"],"reviewers":["baymax"],"ccs":["mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117712","dateCreated":"1579887194","dateModified":"1579887194"},{"type":"reject","author":"baymax","id":"117711","dateCreated":"1579887194","dateModified":"1579887194"},{"type":"update","diffId":"6638","author":"indygreg","id":"43217","dateCreated":"1520210574","dateModified":"1520210574"}],"dateCreated":"1520210574","dateModified":"1579887194","status":"Needs Revision"},{"id":"2682","callsign":"HG","title":"[PoC] changegroup: delete obs markers when applying changegroup","author":"indygreg","summary":"In local-only obsolescence mode, our short-term hack to unhide a\nchangeset is to delete obsolescence markers causing it to be hidden.\nWe need to do this every time a changeset is introduced into the\nrepository.\n\nI was hoping we could implement the unhide logic once, around\ntransaction close time. However, it appears that we'll need to\nteach every mechanism that introduces changesets to unhide\nchangesets because of interaction between those mechanisms and\nvisibility. For example, changegroup application no-ops on incoming\nchangesets that are present but hidden. The code that scans for\n\"new\" changesets is based on changesets between the old and new\nchangelog length. Since the unhidden changeset is possibly older\nthan the old changelog length, we need to either track unhides\nexplicitly or deal with them specially.\n\nThis commit teaches changegroup application to record which changesets\nare in the incoming changegroup so it can scan for relevant\nobsolescence markers after changegroup applications and delete\ntheir markers.\n\nI'm not convinced this is the best approach to the problem. But it's\na start.","testPlan":"","lineCount":"27","dependsOn":["2681"],"reviewers":["baymax"],"ccs":["mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117709","dateCreated":"1579887192","dateModified":"1579887192"},{"type":"reject","author":"baymax","id":"117708","dateCreated":"1579887192","dateModified":"1579887192"},{"type":"update","diffId":"6640","author":"indygreg","id":"43236","dateCreated":"1520210580","dateModified":"1520210580"}],"dateCreated":"1520210580","dateModified":"1579887192","status":"Needs Revision"},{"id":"2681","callsign":"HG","title":"[PoC] scmutil: support local only obsolescence","author":"indygreg","summary":"Now that we have a config option for enabling local-only obsolescence,\nit is time to do something with it.\n\nThis commit teaches cleanupnodes() - which is called after rewrite\noperations - to handle local only obsolescence mode.\n\nIn this mode, we create a backup bundle of the obsoleted changesets -\njust like what happens if obsolescence is disabled. But we don't strip\nthe repo: we keep the original changesets around in a non-visible state.\n\nThe new code verifies that no unstable changesets are introduced in\nlocal-only obsolescence mode.\n\nThe new code hackily only runs if the action is \"amend.\" The intent\nis to make this conditional only on the feature option. However,\ndoing that would have significant test fallout. So we limit to \"amend\"\nfor now.\n\nTODO:\n\n* Better test coverage (I think the \"(testcase !)\" syntax might be\n subtly wrong by flagging output as optional and not required).\n* Delete obsolescence markers when we pull and unbundle from the\n bundle.\n* Support pulling locally-hidden heads.","testPlan":"","lineCount":"143","dependsOn":["2680"],"reviewers":["baymax"],"ccs":["mharbison72","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117706","dateCreated":"1579887191","dateModified":"1579887191"},{"type":"reject","author":"baymax","id":"117705","dateCreated":"1579887191","dateModified":"1579887191"},{"type":"comment","comment":"re: the \"(testcase !)\" syntax- I agree that it would be better if \"(false !)\" means the line is *not* present, instead of optional.\n\nI made an attempt to do that, but somehow I came up with a test in test-run-tests.t that failed there, but the exact same test ran fine in another *.t. I wondered if it was a case of run-tests.py processing it for a test inside test-run-tests.t, and then the main instance of run-tests.py re-processing it. If I can find that code, I can post it if you think it might be useful. But I've long forgotten the nuance in that code. ","author":"mharbison72","id":"43337","dateCreated":"1520216552","dateModified":"1520216552"},{"type":"update","diffId":"6639","author":"indygreg","id":"43226","dateCreated":"1520210577","dateModified":"1520210577"}],"dateCreated":"1520210577","dateModified":"1579887191","status":"Needs Revision"},{"id":"2588","callsign":"HG","title":"commit: adds multiline commit message support(issue5616)","author":"sangeet259","summary":"The earlier functionality used to ignore the all but last -m flag's value.\nIt used to store the arguments information in a state dict and then overwrites each\nsubsequent value of -m in the 'message' key. This patch intercepts the message flag and\nchecks if it is already empty. In case it is not empty, add the current value of -m flag to\nthe message key with a leading '\\n' character. This makes every subsequent passed -m flag\nas the new line message of the commit.","testPlan":"","lineCount":"28","dependsOn":[],"reviewers":["baymax"],"ccs":["durin42","tom.prince","yuja","pulkit","jeffpc","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117703","dateCreated":"1579887189","dateModified":"1579887189"},{"type":"reject","author":"baymax","id":"117702","dateCreated":"1579887189","dateModified":"1579887189"},{"type":"comment","comment":">>! In D2588#44645, @sangeet259 wrote:\n> Since the current code just overwrites message each time with the newer. What can be done to avoid losing the earlier message values?\n\nYou should look how we handle multiple `--rev` flags. That will help you in this case.","author":"pulkit","id":"44677","dateCreated":"1520666278","dateModified":"1520666278"},{"type":"comment","comment":"Since the current code just overwrites message each time with the newer. What can be done to avoid losing the earlier message values?\n","author":"sangeet259","id":"44645","dateCreated":"1520655918","dateModified":"1520655918"},{"type":"inline","comment":"agreed","replyTo":"42705","isNewFile":"1","line":"847","lineLength":"0","path":"tests\/test-commit.t","diffId":"6537","author":"durin42","id":"43618","dateCreated":"1520437801","dateModified":"1520437801"},{"type":"comment","comment":"@pulkit Yeah, this rather a not so elegant hack. How can it be parsed in hg commit? \nAs the first message passed is overwritten by the second one at this step only. :\/\n\n@yuja I think maybe subclassing the customopt may be a fair choice.","author":"sangeet259","id":"43614","dateCreated":"1520437520","dateModified":"1520437520"},{"type":"inline","comment":"Right. Alternatively, we could add a subclass of customopt, but I don't know which\nwould be nicer.\n\nFWIW, I'm kinda -1 on this feature, but I have no strong opinion and Git is the\ncurrent standard.","replyTo":"42704","isNewFile":"1","line":"365","lineLength":"0","path":"mercurial\/fancyopts.py","diffId":"6537","author":"yuja","id":"42772","dateCreated":"1520184244","dateModified":"1520184244"},{"type":"inline","comment":"starting with a newline seems awkward.","replyTo":null,"isNewFile":"1","line":"847","lineLength":"0","path":"tests\/test-commit.t","diffId":"6537","author":"pulkit","id":"42705","dateCreated":"1520181862","dateModified":"1520181862"},{"type":"inline","comment":"I think this is not the right place to have this hack. We should have this as a part of `hg commit` code rather.","replyTo":null,"isNewFile":"1","line":"365","lineLength":"0","path":"mercurial\/fancyopts.py","diffId":"6537","author":"pulkit","id":"42704","dateCreated":"1520181862","dateModified":"1520181862"},{"type":"update","diffId":"6537","author":"sangeet259","id":"42559","dateCreated":"1520149348","dateModified":"1520149348"},{"type":"comment","comment":"@jeffpc That means two new lines. Shall I edit this patch to effect that?\n","author":"sangeet259","id":"42558","dateCreated":"1520142981","dateModified":"1520147672"},{"type":"update","diffId":"6536","author":"sangeet259","id":"42557","dateCreated":"1520139879","dateModified":"1520139879"},{"type":"comment","author":"sangeet259","id":"41893","dateCreated":"1520098879","dateModified":"1520098898"},{"type":"comment","comment":"FWIW, this is slightly different behavior from what git does. There, each -m is added as a separate *paragraph*. IOW,\n\n\n```\n$ git commit -m \"first\" -m \"second\"\n```\n\ncreates:\n\n```\nfirst\n\nsecond\n```","author":"jeffpc","id":"41892","dateCreated":"1520098727","dateModified":"1520098727"},{"type":"update","diffId":"6438","author":"sangeet259","id":"41882","dateCreated":"1520098029","dateModified":"1520098029"}],"dateCreated":"1520098029","dateModified":"1579887189","status":"Needs Revision"},{"id":"2057","callsign":"HG","title":"rust implementation of hg status","author":"Ivzhh","summary":"* implementation of revlog v1\n* parsing changelog, manifest, dirstate\n* use .hgignore in repo root\n* comparable performance with current hg status (Linux & Mac: slightly faster, Windows: slightly slower)\n* use hg r-status as subcommand, in this case, bypass python engine","testPlan":"","lineCount":"3066","dependsOn":[],"reviewers":["kevincox","baymax"],"ccs":["quark","yuja","glandium","krbullock","indygreg","durin42","kevincox","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117700","dateCreated":"1579887188","dateModified":"1579887188"},{"type":"reject","author":"baymax","id":"117699","dateCreated":"1579887188","dateModified":"1579887188"},{"type":"inline","comment":"I meant safe not as it it didn't need the unsafe keyword, but in that the use of the `unsafe` block is safe.\n\nIt should really be called the `trust_me,_I_know_this_is_safe` block. But since you are not getting the compiler checking it is often useful to add a comment why the action you are performing is correct. In this case it is correct because the caller initializes this variable before the function is called.","replyTo":"46950","isNewFile":"1","line":"91","lineLength":"0","path":"rust\/hgbase85\/src\/base85.rs","diffId":"6724","author":"kevincox","id":"47428","dateCreated":"1521888284","dateModified":"1521888284"},{"type":"inline","comment":"Actually I didn't realize that RwLock doesn't get a regular `get()` since it is doing a compile time borrow check. https:\/\/doc.rust-lang.org\/std\/sync\/struct.RwLock.html#method.get_mut. My mistake, the code is fine.","replyTo":"46960","isNewFile":"1","line":"136","lineLength":"0","path":"rust\/hgstorage\/src\/local_repo.rs","diffId":"6724","author":"kevincox","id":"47427","dateCreated":"1521888284","dateModified":"1521888284"},{"type":"inline","comment":"Does it make sense to make `DirStateEntry.mtime` be a `std::time::SystemTime` and convert upon reading the structure in?\n\nIf not I would prefer doing the conversion here:\n\n```\nelse if mtd.modified().unwrap() == UNIX_EPOCH + Duration::from_secs(dir_entry.mtime as u64) {\n```\n\n(Maybe extract the system time to higher up, or even a helper function on dir_entry)","replyTo":null,"isNewFile":"1","line":"263","lineLength":"0","path":"rust\/hgstorage\/src\/dirstate.rs","diffId":"7188","author":"kevincox","id":"47426","dateCreated":"1521888284","dateModified":"1521888284"},{"type":"inline","comment":"Sorry, I misunderstood the logic. You can do this:\n\n```\ndiff -r ccc683587fdb rust\/hgstorage\/src\/dirstate.rs\n--- a\/rust\/hgstorage\/src\/dirstate.rs\tSat Mar 24 10:05:53 2018 +0000\n+++ b\/rust\/hgstorage\/src\/dirstate.rs\tSat Mar 24 10:14:58 2018 +0000\n@@ -184,8 +184,7 @@\n continue;\n }\n \n- if self.dir_state_map.contains_key(rel_path) {\n- let dir_entry = &self.dir_state_map[rel_path];\n+ if let Some(dir_entry) = self.dir_state_map.get(rel_path) {\n files_not_in_walkdir.remove(rel_path);\n DirState::check_status(&mut res, abs_path, rel_path, dir_entry);\n } else if !matcher.check_path_ignored(rel_path.to_str().unwrap()) {\n```","replyTo":"46959","isNewFile":"1","line":"170","lineLength":"0","path":"rust\/hgstorage\/src\/dirstate.rs","diffId":"6724","author":"kevincox","id":"47425","dateCreated":"1521888284","dateModified":"1521888284"},{"type":"inline","comment":"Switch the return type to `std::io::Result` and then you can have\n\n```\nlet metadata = p.metadata()?;\nlet mtime = metadata.modified()?;\n\/\/ ...\n```","replyTo":null,"isNewFile":"1","line":"103","lineLength":"0","path":"rust\/hgstorage\/src\/dirstate.rs","diffId":"7188","author":"kevincox","id":"47424","dateCreated":"1521888284","dateModified":"1521888284"},{"type":"inline","comment":"A link to the mentioned wiki page would be very helpful to readers.","replyTo":null,"isNewFile":"1","line":"50","lineLength":"0","path":"rust\/hgstorage\/src\/config.rs","diffId":"7188","author":"kevincox","id":"47423","dateCreated":"1521888284","dateModified":"1521888284"},{"type":"inline","comment":"These are `HashSet`'s which don't have a defined iterator order. IIRC the python implementation sorts the results which is probably desirable.","replyTo":null,"isNewFile":"1","line":"260","lineLength":"0","path":"rust\/hgcli\/src\/main.rs","diffId":"7188","author":"kevincox","id":"47422","dateCreated":"1521888284","dateModified":"1521888284"},{"type":"inline","comment":"If this computation only depends on `len` it would be nice to put it in a helper function.","replyTo":null,"isNewFile":"1","line":"105","lineLength":"0","path":"rust\/hgbase85\/src\/base85.rs","diffId":"7188","author":"kevincox","id":"47421","dateCreated":"1521888284","dateModified":"1521888284"},{"type":"inline","comment":"I get that, but I still think it makes the code easier to read when the python-interop and the logic as separated where it is easy to do so.","replyTo":"46947","isNewFile":"1","line":"23","lineLength":"0","path":"rust\/hgbase85\/src\/base85.rs","diffId":"6724","author":"kevincox","id":"47420","dateCreated":"1521888284","dateModified":"1521888284"},{"type":"comment","comment":"The latest changes are looking really good. I have a couple more comments but I didn't have time for a full review. I'll try to get more reviewed tomorrow. It seems that you still have a lot of stuff still in-flight so I'll try to slowly review the changes as I have time. If you want input\/feedback on any particular part just ask and I will prioritize it.\n\nThis change is very large so it might be worth splitting off a smaller component and getting that submitted first. However I do realize that for starting out it is often helpful to get some actual use cases implemented before committing the base structures.","author":"kevincox","id":"47419","dateCreated":"1521888284","dateModified":"1521888284"},{"type":"comment","comment":">>! In D2057#46980, @Ivzhh wrote:\n>>>! In D2057#46726, @yuja wrote:\n>>>> I think the only place where you would need to do os-specific code is when\n>>>> doing serialization and serialization\n>>> \n>>> Yes, that will be feasible in strictly typed language like Rust.\n>> \n>> To be clear, I meant serialization\/deserialization between filesystem path and\n>> internal dirstate\/manifest path, not between dirstate storage and in-memory\n>> dirstate object.\n> \n> I guess your suggestion is like this: @yuja\n> \n> 1. if it is windows and the code page is MBCS, try to decode the paths read from manifest and dirstate into unicode equivalent\n> 2. use utf internally and with rust IO api\n> 3. when writing back to dirstate and manifest, encode utf to MBCS\n\nNo. My suggestion is:\n\n1. keep manifest\/dirstate paths as bytes (which are probably wrapped by some type, say HgPath)\n2. but we want to use Rust's standard library for I\/O\n3. so, add utility function\/trait to convert HgPath to Path\/PathBuf, where MBCS-Wide conversion\n will occur.\n\nI think raw byte paths will be needed to build store paths (e.g. `.hg\/store\/data\/~2eclang-format.i`).\n\nhttps:\/\/www.mercurial-scm.org\/repo\/hg\/file\/4.5.2\/mercurial\/store.py","author":"yuja","id":"47287","dateCreated":"1521730814","dateModified":"1521730814"},{"type":"comment","comment":">>! In D2057#46726, @yuja wrote:\n>>> I think the only place where you would need to do os-specific code is when\n>>> doing serialization and serialization\n>> \n>> Yes, that will be feasible in strictly typed language like Rust.\n> \n> To be clear, I meant serialization\/deserialization between filesystem path and\n> internal dirstate\/manifest path, not between dirstate storage and in-memory\n> dirstate object.\n\nI guess your suggestion is like this: @yuja\n\n1. if it is windows and the code page is MBCS, try to decode the paths read from manifest and dirstate into unicode equivalent\n2. use utf internally and with rust IO api\n3. when writing back to dirstate and manifest, encode utf to MBCS\n\nPlease let me know if I have misunderstanding. Thank you!","author":"Ivzhh","id":"46981","dateCreated":"1521662441","dateModified":"1521662461"},{"type":"inline","comment":"I guess I did this because I met some empty change delta in the beginning. I think I won't try to parallelize unzip for now.","replyTo":"43866","isNewFile":"1","line":"290","lineLength":"3","path":"rust\/hgstorage\/src\/revlog_v1.rs","diffId":"6724","author":"Ivzhh","id":"46964","dateCreated":"1521658541","dateModified":"1521658541"},{"type":"inline","comment":"I think it explains why in mercurial repo, rust version is significantly faster. I am working on cpu future, but I did not finalize design style yet. I will keep working on that.","replyTo":"43867","isNewFile":"1","line":"279","lineLength":"0","path":"rust\/hgstorage\/src\/revlog_v1.rs","diffId":"6724","author":"Ivzhh","id":"46963","dateCreated":"1521658541","dateModified":"1521658541"},{"type":"inline","comment":"This part, including the stream-style, is from python part. I will update later with xi-rope.","replyTo":"43969","isNewFile":"1","line":"51","lineLength":"0","path":"rust\/hgstorage\/src\/mpatch.rs","diffId":"6724","author":"Ivzhh","id":"46962","dateCreated":"1521658541","dateModified":"1521658541"},{"type":"inline","comment":"I borrow this logic as whole from python code. It will need sometime to re-translate to non-pointer-arithmetic way.","replyTo":"43949","isNewFile":"1","line":"14","lineLength":"0","path":"rust\/hgstorage\/src\/matcher.rs","diffId":"6724","author":"Ivzhh","id":"46961","dateCreated":"1521658541","dateModified":"1521658541"},{"type":"inline","comment":"I think LRU will update reference count (or timestamp) when the data is accessed.","replyTo":"43942","isNewFile":"1","line":"136","lineLength":"0","path":"rust\/hgstorage\/src\/local_repo.rs","diffId":"6724","author":"Ivzhh","id":"46960","dateCreated":"1521658541","dateModified":"1521658541"},{"type":"inline","comment":"I kind of get borrow check compile error here. Later I use Occupied() when possible.","replyTo":"43930","isNewFile":"1","line":"170","lineLength":"0","path":"rust\/hgstorage\/src\/dirstate.rs","diffId":"6724","author":"Ivzhh","id":"46959","dateCreated":"1521658541","dateModified":"1521658541"},{"type":"inline","comment":"I add the error handling back","replyTo":"43923","isNewFile":"1","line":"161","lineLength":"0","path":"rust\/hgstorage\/src\/dirstate.rs","diffId":"6724","author":"Ivzhh","id":"46958","dateCreated":"1521658541","dateModified":"1521658541"},{"type":"inline","comment":"For the filter, I follow the example in the walkdir doc. I guess what I want is to skip the dir for later recursive visiting. ","replyTo":"43921","isNewFile":"1","line":"152","lineLength":"0","path":"rust\/hgstorage\/src\/dirstate.rs","diffId":"6724","author":"Ivzhh","id":"46957","dateCreated":"1521658541","dateModified":"1521658541"},{"type":"inline","comment":"I think dir state needs to 1. read existing one; 2. create one if not exits; maybe private for now.","replyTo":"43916","isNewFile":"1","line":"108","lineLength":"0","path":"rust\/hgstorage\/src\/dirstate.rs","diffId":"6724","author":"Ivzhh","id":"46956","dateCreated":"1521658541","dateModified":"1521658541"},{"type":"inline","comment":"I remember the python hg uses the name, in the beginning, I tried to replicate py-hg's behaviour. But I think it needs to be renamed. I agree with you.","replyTo":"43928","isNewFile":"1","line":"48","lineLength":"0","path":"rust\/hgstorage\/src\/dirstate.rs","diffId":"6724","author":"Ivzhh","id":"46955","dateCreated":"1521658541","dateModified":"1521658541"},{"type":"inline","comment":"I like to_owned(), I will them in later occasions. Thank you!","replyTo":"43913","isNewFile":"1","line":"78","lineLength":"0","path":"rust\/hgstorage\/src\/config.rs","diffId":"6724","author":"Ivzhh","id":"46954","dateCreated":"1521658541","dateModified":"1521658541"},{"type":"inline","comment":"Sure, I will use v1 only for now. In the beginning I kinda over designed this part.","replyTo":"43865","isNewFile":"1","line":"95","lineLength":"0","path":"rust\/hgstorage\/src\/config.rs","diffId":"6724","author":"Ivzhh","id":"46953","dateCreated":"1521658541","dateModified":"1521658541"},{"type":"inline","comment":"I guess I will use the rest info later. hg seems put some meta data in the commit comments. I will keep it for now. Thank you!","replyTo":"43911","isNewFile":"1","line":"31","lineLength":"0","path":"rust\/hgstorage\/src\/changelog.rs","diffId":"6724","author":"Ivzhh","id":"46952","dateCreated":"1521658541","dateModified":"1521658541"},{"type":"inline","comment":"Thank you for the suggestion! I guess I need to extend clap later to support hg style command line. Right now whenever clap cannot handle the argument parsing, I will redirect the arguments to hg directly.","replyTo":"43864","isNewFile":"1","line":"233","lineLength":"28","path":"rust\/hgcli\/src\/main.rs","diffId":"6724","author":"Ivzhh","id":"46951","dateCreated":"1521658541","dateModified":"1521658541"},{"type":"inline","comment":"when I removed the unsafe, I got error: error[E0133]: use of mutable static requires unsafe function or block","replyTo":"43908","isNewFile":"1","line":"91","lineLength":"0","path":"rust\/hgbase85\/src\/base85.rs","diffId":"6724","author":"Ivzhh","id":"46950","dateCreated":"1521658541","dateModified":"1521658541"},{"type":"inline","comment":"I guess it is because NLL. When I started the work, rust compiler reported borrow check error on this part. I later read an article talking about NLL update in rust. But before that, I use the braces to avoid the error.","replyTo":"43901","isNewFile":"1","line":"46","lineLength":"0","path":"rust\/hgbase85\/src\/base85.rs","diffId":"6724","author":"Ivzhh","id":"46949","dateCreated":"1521658541","dateModified":"1521658541"},{"type":"inline","comment":"pad is a bool, however when I checked it in hg-python, int are passed to the function. I guess I need to update cpython wrapper for this, a more broad logic conversion.","replyTo":"43900","isNewFile":"1","line":"23","lineLength":"0","path":"rust\/hgbase85\/src\/base85.rs","diffId":"6724","author":"Ivzhh","id":"46948","dateCreated":"1521658541","dateModified":"1521658541"},{"type":"inline","comment":"This crate is my previous try to integrate rust into hg. Right now I guess mine main pursue is to add hg r-* commands for rust. I will follow your suggestion when I am implementing the wire protocol and reuse the code for pure rust crate.","replyTo":"43897","isNewFile":"1","line":"23","lineLength":"0","path":"rust\/hgbase85\/src\/base85.rs","diffId":"6724","author":"Ivzhh","id":"46947","dateCreated":"1521658541","dateModified":"1521658541"},{"type":"inline","comment":"It should be any &[u8], but the current cpython crate doesn't wrap for &[u8]. I think I need to fork and add that part. I put it in my checklist now.","replyTo":"43898","isNewFile":"1","line":"23","lineLength":"0","path":"rust\/hgbase85\/src\/base85.rs","diffId":"6724","author":"Ivzhh","id":"46946","dateCreated":"1521658541","dateModified":"1521658541"},{"type":"comment","comment":" - add revlog and mpatch facilities\n - add changelog parsing\n - add manifest parsing\n - path encoding for data store\n - add dirstate and matcher facilities\n - add local repository and the supporting modules\n - use cargo fmt to format code\n - add hg r-status command\n - bincode 1.0.0 is a bit slow in my test\n - delay pattern matching during dir walk\n - optimize out trie and enable CoreXL profiling\n - use hashmap\n - remove thread pool\n - rust default read is not buf-ed, this is the key of slowness\n - change to globset\n - convert glob to regex\n - hg ignore patterns are all converted to regex (as hg does), and now it is faster\n - filter dir early to prevent walking\n - Update matcher mod after testing Mozilla unified repo\n - bug fix: use byte literals instead of numbers\n - hg store path encoding is per byte style, update code according to Kevin Cox's comments\n - update matcher testing according to Match interface change\n - If clap fails to recognize r-* subcommands, then run python-version hg\n - changelog coding style revised\n - remove legacy revlog v0 and unfinished v2.\n - partially revise the dirstate reviews\n - remove duplicated build.rs, let the executable module guarantee the python\n - use cursor in base85 encoding, reducing raw index-math\n - use cursor in base85 decoding, reducing raw index-math\n - dirstate update according to review comments\n - config update according to review comments\n - mpatch rename to more meaningful names\n - simplify matcher as when there is no syntax named in the beginning, use regexp\n - local repo coding style update\n - dirstate coding style update\n - manifest coding style update\n","author":"Ivzhh","id":"46944","dateCreated":"1521656608","dateModified":"1521656608"},{"type":"update","diffId":"7188","author":"Ivzhh","id":"46942","dateCreated":"1521656608","dateModified":"1521656608"},{"type":"comment","comment":"Ah, I forgot to consider the python interop. Now the need for that crate makes sense. Thanks for explaining.","author":"kevincox","id":"46733","dateCreated":"1521627628","dateModified":"1521627628"},{"type":"comment","comment":">> I think the only place where you would need to do os-specific code is when\n>> doing serialization and serialization\n> \n> Yes, that will be feasible in strictly typed language like Rust.\n\nTo be clear, I meant serialization\/deserialization between filesystem path and\ninternal dirstate\/manifest path, not between dirstate storage and in-memory\ndirstate object.","author":"yuja","id":"46726","dateCreated":"1521613817","dateModified":"1521613817"},{"type":"comment","comment":"> I think the only place where you would need to do os-specific code is when\n> doing serialization and serialization\n\nYes, that will be feasible in strictly typed language like Rust.\n\n> which I think should be handled by https:\/\/doc.rust-lang.org\/std\/os\/unix\/ffi\/trait.OsStringExt.html\n> and https:\/\/doc.rust-lang.org\/std\/os\/windows\/ffi\/trait.OsStringExt.html.\n\nNot true for Windows because Rust uses Unicode (UTF-16-ish) API, whereas\nPython 2 does ANSI. We need to convert a \"wide\" string to a locale-dependent string.\n\nMaybe the local-encoding crate will do that for us?\n\n","author":"yuja","id":"46723","dateCreated":"1521607475","dateModified":"1521607475"},{"type":"comment","comment":"I'm not a windows expert but it seems like the rust OsStr, Path and filesystem APIs should handle these conversions for you. I think the only place where you would need to do os-specific code is when doing serialization and serialization which I think should be handled by https:\/\/doc.rust-lang.org\/std\/os\/unix\/ffi\/trait.OsStringExt.html and https:\/\/doc.rust-lang.org\/std\/os\/windows\/ffi\/trait.OsStringExt.html.","author":"kevincox","id":"46685","dateCreated":"1521577349","dateModified":"1521577349"},{"type":"comment","comment":"https:\/\/crates.io\/crates\/local-encoding seems to be the right choice.","author":"quark","id":"46681","dateCreated":"1521573831","dateModified":"1521573831"},{"type":"comment","comment":"> I am looking at Mozilla's rust winapi bindings, let me see if I can directly wrap around [winapi::um::fileapi::FindFirstFileA](https:\/\/docs.rs\/winapi\/*\/x86_64-pc-windows-msvc\/winapi\/um\/fileapi\/fn.FindFirstFileA.html)\n\nThat's probably a hard way. I was thinking of something converting\nbetween OsStr (i.e. Path) and MBCS bytes by using Win32 API, instead\nof calling out the \"A\" API.\n\nhttps:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/dd319072(v=vs.85).aspx\n\nWe don't do that in Python, but Rust's type system will help making it right.","author":"yuja","id":"44688","dateCreated":"1520680806","dateModified":"1520680806"},{"type":"comment","comment":">>! In D2057#44269, @yuja wrote:\n>>> Reading that page it seems to claim that filenames should be utf8, not bytes. If utf8, this is what the code does, but if it is bytes that definitely won't work.\n>> \n>> IIRC it's bytes everyplace except Windows, where we pretend utf8 is real?\n> \n> It's MBCS (i.e. ANSI multi-byte characters) on Windows. The plain was to support\n> both MBCS and UTF-8-variant on Windows, but that isn't a thing yet.\n> \n> Perhaps we'll have to write a platform compatibility layer (or serialization\/deserialization\n> layer) on top of the Rust's file API, something like vfs.py we have in Python code.\n\nThank you for confirming that, I am a bit confusing when I read Encoding Plan wiki page. I am looking at Mozilla's rust winapi bindings, let me see if I can directly wrap around [winapi::um::fileapi::FindFirstFileA](https:\/\/docs.rs\/winapi\/*\/x86_64-pc-windows-msvc\/winapi\/um\/fileapi\/fn.FindFirstFileA.html)","author":"Ivzhh","id":"44295","dateCreated":"1520618349","dateModified":"1520618349"},{"type":"comment","comment":">> Reading that page it seems to claim that filenames should be utf8, not bytes. If utf8, this is what the code does, but if it is bytes that definitely won't work.\n> \n> IIRC it's bytes everyplace except Windows, where we pretend utf8 is real?\n\nIt's MBCS (i.e. ANSI multi-byte characters) on Windows. The plain was to support\nboth MBCS and UTF-8-variant on Windows, but that isn't a thing yet.\n\nPerhaps we'll have to write a platform compatibility layer (or serialization\/deserialization\nlayer) on top of the Rust's file API, something like vfs.py we have in Python code.","author":"yuja","id":"44270","dateCreated":"1520598781","dateModified":"1520598781"},{"type":"comment","comment":"Hi everyone,\n\nThank you for your encouragements and comments! I will follow up with all comments and update the code soon.\n\n@indygreg It is a great idea to test on Mozilla repo, actually I found several things interesting:\n\n1. I found a bug in my code (shame on me): because I did not use byte literal, and I made a typo. This triggers problem in Mozilla unified repo\n2. A regexp pattern in hgignore in Mozilla unified repo is not supported by rust's regex crate, a.k.a. \"(?!)\". I choose to ignore these unsupported patterns.\n3. My version is slower in this repo: 70s (hg) and 90s (mine). CodeXL reveals that the mpatch::collect() function uses 63% of the running time. I think I need to optimize it somehow.\n\nI totally agree with @kevincox that I did not sort well on char\/u8\/str\/String\/Path\/PathBuf. The first bug is caused by this. I need to improve them.\n\nThank you everyone!","author":"Ivzhh","id":"44180","dateCreated":"1520558265","dateModified":"1520558265"},{"type":"comment","comment":"Rust has platform independent types [[ https:\/\/doc.rust-lang.org\/stable\/std\/path\/struct.PathBuf.html | `PathBuf` ]] and [[ https:\/\/doc.rust-lang.org\/stable\/std\/path\/struct.Path.html | `&Path` ]] for paths and [[ https:\/\/doc.rust-lang.org\/stable\/std\/ffi\/struct.OsString.html | `OsString` ]] and [[ https:\/\/doc.rust-lang.org\/stable\/std\/ffi\/struct.OsStr.html | `&OsStr` ]] for strings (owned and references respectively. They do have os-specific extensions but as long as you don't use them it should be cross platform. That being said, if you are serializing and deserializing them you may need to write some platform dependant code.","author":"kevincox","id":"43991","dateCreated":"1520536377","dateModified":"1520536377"},{"type":"comment","comment":">>! In D2057#43989, @durin42 wrote:\n>>>! In D2057#43988, @kevincox wrote:\n>>>>! In D2057#43987, @durin42 wrote:\n>>> \n>>> Mercurial tries to be principled about always treating filenames as bytes. AIUI https:\/\/www.mercurial-scm.org\/wiki\/WindowsUTF8Plan is still the plan of record there?\n>> \n>> Reading that page it seems to claim that filenames should be utf8, not bytes. If utf8, this is what the code does, but if it is bytes that definitely won't work.\n> \n> IIRC it's bytes everyplace except Windows, where we pretend utf8 is real?\n> \n> We may have to make adjustments to this plan on macOS with APFS, but I'm not sure about that yet.\n\nI think we want to express a path as a dedicated type which has different underlying storage depending on the platform (bytes on Linux, UTF-16 on Windows). All filesystem operations should take a `Path` instance to operate on. This is the only way to cleanly round trip filenames between the OS, the application, and back to the OS. That leaves us with the hard problem of normalizing Mercurial's storage representation of paths (bytes) with the operating system's. But this world is strictly better than today, where we lose path data from the OS because we use POSIX APIs.\n\nFWIW, Python 3 rewrote the I\/O layer to use Win32 APIs everywhere. Combined with the `pathlib` types, I'm pretty sure Python 3 can round trip paths on Windows. I also think Rust's path type(s) have OS-dependent functionality.","author":"indygreg","id":"43990","dateCreated":"1520534077","dateModified":"1520534077"},{"type":"comment","comment":">>! In D2057#43988, @kevincox wrote:\n>>>! In D2057#43987, @durin42 wrote:\n>> \n>> Mercurial tries to be principled about always treating filenames as bytes. AIUI https:\/\/www.mercurial-scm.org\/wiki\/WindowsUTF8Plan is still the plan of record there?\n> \n> Reading that page it seems to claim that filenames should be utf8, not bytes. If utf8, this is what the code does, but if it is bytes that definitely won't work.\n\nIIRC it's bytes everyplace except Windows, where we pretend utf8 is real?\n\nWe may have to make adjustments to this plan on macOS with APFS, but I'm not sure about that yet.","author":"durin42","id":"43989","dateCreated":"1520533145","dateModified":"1520533145"},{"type":"comment","comment":">>! In D2057#43987, @durin42 wrote:\n> \n> Mercurial tries to be principled about always treating filenames as bytes. AIUI https:\/\/www.mercurial-scm.org\/wiki\/WindowsUTF8Plan is still the plan of record there?\n\nReading that page it seems to claim that filenames should be utf8, not bytes. If utf8, this is what the code does, but if it is bytes that definitely won't work.","author":"kevincox","id":"43988","dateCreated":"1520532520","dateModified":"1520532520"},{"type":"comment","comment":">>! In D2057#43892, @kevincox wrote:\n> On a higher level, all of these code appears to be treating file names as strings. This isn't really true and will disallow some valid file names. Maybe we should stick with bytes throughout. Of course this makes windows filepaths difficult because they are actually (utf16) strings.\n\nMercurial tries to be principled about always treating filenames as bytes. AIUI https:\/\/www.mercurial-scm.org\/wiki\/WindowsUTF8Plan is still the plan of record there?","author":"durin42","id":"43987","dateCreated":"1520531899","dateModified":"1520531899"},{"type":"inline","comment":"Take a `&str`.","replyTo":null,"isNewFile":"1","line":"62","lineLength":"0","path":"rust\/hgstorage\/src\/path_encoding.rs","diffId":"6724","author":"kevincox","id":"43985","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"```\nfn escape(out: &mut String, b: char) {\n unimplemented!()\n}\n\npub fn encode_path(path: &str) -> String {\n let mut out = String::with_capacity(path.len());\n\n for c in path.bytes() {\n let c = c as char;\n match c {\n 'A'...'Z' => {\n out.push('_');\n out.push(c.to_ascii_lowercase());\n }\n '\\\\' | ':' | '*' | '?' | '\"' | '<' | '>' | '|' => {\n escape(&mut out, c);\n }\n \/\/ The rest of the printable range.\n ' '...'~' => {\n out.push(c);\n }\n _ => {\n escape(&mut out, c);\n }\n }\n }\n\n out\n}\n```\nhttps:\/\/godbolt.org\/g\/3WCQs3","replyTo":null,"isNewFile":"1","line":"57","lineLength":"0","path":"rust\/hgstorage\/src\/path_encoding.rs","diffId":"6724","author":"kevincox","id":"43984","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"Don't pass a `char` by reference. Also it seems your function wants a `u8`.","replyTo":null,"isNewFile":"1","line":"11","lineLength":"0","path":"rust\/hgstorage\/src\/path_encoding.rs","diffId":"6724","author":"kevincox","id":"43983","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"Use a String.","replyTo":null,"isNewFile":"1","line":"35","lineLength":"0","path":"rust\/hgstorage\/src\/path_encoding.rs","diffId":"6724","author":"kevincox","id":"43982","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"`encode_file_name`?","replyTo":null,"isNewFile":"1","line":"34","lineLength":"0","path":"rust\/hgstorage\/src\/path_encoding.rs","diffId":"6724","author":"kevincox","id":"43981","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"Take a `&str`","replyTo":null,"isNewFile":"1","line":"34","lineLength":"0","path":"rust\/hgstorage\/src\/path_encoding.rs","diffId":"6724","author":"kevincox","id":"43980","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"```\np.ends_with(\".i\") || p.ends_with(\".d\")\n```","replyTo":null,"isNewFile":"1","line":"25","lineLength":"0","path":"rust\/hgstorage\/src\/path_encoding.rs","diffId":"6724","author":"kevincox","id":"43979","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"This isn't necessary.","replyTo":null,"isNewFile":"1","line":"23","lineLength":"0","path":"rust\/hgstorage\/src\/path_encoding.rs","diffId":"6724","author":"kevincox","id":"43978","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"I don't think you need this.","replyTo":null,"isNewFile":"1","line":"22","lineLength":"0","path":"rust\/hgstorage\/src\/path_encoding.rs","diffId":"6724","author":"kevincox","id":"43977","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"`Vec<char>` is odd. Is there any reason not to use a `String` or `Vec<u8>`","replyTo":null,"isNewFile":"1","line":"11","lineLength":"0","path":"rust\/hgstorage\/src\/path_encoding.rs","diffId":"6724","author":"kevincox","id":"43976","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"c should be a `u8`.","replyTo":null,"isNewFile":"1","line":"7","lineLength":"0","path":"rust\/hgstorage\/src\/path_encoding.rs","diffId":"6724","author":"kevincox","id":"43975","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"const HEX_DIGIT: [u8; 16] = *b\"0123456789abcdef\";","replyTo":null,"isNewFile":"1","line":"5","lineLength":"0","path":"rust\/hgstorage\/src\/path_encoding.rs","diffId":"6724","author":"kevincox","id":"43974","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"```\nassert!(!frags.is_empty());\n```","replyTo":null,"isNewFile":"1","line":"137","lineLength":"0","path":"rust\/hgstorage\/src\/mpatch.rs","diffId":"6724","author":"kevincox","id":"43973","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"Please explain.","replyTo":null,"isNewFile":"1","line":"120","lineLength":"0","path":"rust\/hgstorage\/src\/mpatch.rs","diffId":"6724","author":"kevincox","id":"43972","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"Make this one line and don't bother renaming.","replyTo":null,"isNewFile":"1","line":"86","lineLength":"0","path":"rust\/hgstorage\/src\/mpatch.rs","diffId":"6724","author":"kevincox","id":"43971","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"```\nfor &Fragment{frag_len, frag_ofs} in list.iter().rev()\n```","replyTo":null,"isNewFile":"1","line":"68","lineLength":"0","path":"rust\/hgstorage\/src\/mpatch.rs","diffId":"6724","author":"kevincox","id":"43970","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"It seems weird to take a cursor to a vec if you are just going to do an absolute seek. Can it work with `&mut [u8]`?","replyTo":null,"isNewFile":"1","line":"51","lineLength":"0","path":"rust\/hgstorage\/src\/mpatch.rs","diffId":"6724","author":"kevincox","id":"43969","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"`vec![0; count]` works. (The arguments might be the other way around).","replyTo":null,"isNewFile":"1","line":"54","lineLength":"0","path":"rust\/hgstorage\/src\/mpatch.rs","diffId":"6724","author":"kevincox","id":"43968","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"`mov` is overly shortened and generic.","replyTo":null,"isNewFile":"1","line":"51","lineLength":"0","path":"rust\/hgstorage\/src\/mpatch.rs","diffId":"6724","author":"kevincox","id":"43967","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"`pull` is very generic.","replyTo":null,"isNewFile":"1","line":"35","lineLength":"0","path":"rust\/hgstorage\/src\/mpatch.rs","diffId":"6724","author":"kevincox","id":"43966","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"```\nstruct Fragment {\n len: u32,\n offset: u32,\n}\n```","replyTo":null,"isNewFile":"1","line":"24","lineLength":"0","path":"rust\/hgstorage\/src\/mpatch.rs","diffId":"6724","author":"kevincox","id":"43965","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"s\/f\/fragment\/","replyTo":null,"isNewFile":"1","line":"40","lineLength":"0","path":"rust\/hgstorage\/src\/mpatch.rs","diffId":"6724","author":"kevincox","id":"43964","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"If you are unwrapping the `pop` there is no need for the prior check.","replyTo":null,"isNewFile":"1","line":"40","lineLength":"0","path":"rust\/hgstorage\/src\/mpatch.rs","diffId":"6724","author":"kevincox","id":"43963","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"Maybe it's just me but I think it is more common to put the source before the destination.","replyTo":null,"isNewFile":"1","line":"35","lineLength":"0","path":"rust\/hgstorage\/src\/mpatch.rs","diffId":"6724","author":"kevincox","id":"43962","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"```\nassert!(!src.is_empty())\n```","replyTo":null,"isNewFile":"1","line":"39","lineLength":"0","path":"rust\/hgstorage\/src\/mpatch.rs","diffId":"6724","author":"kevincox","id":"43961","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"Spell these out please.","replyTo":null,"isNewFile":"1","line":"13","lineLength":"0","path":"rust\/hgstorage\/src\/mpatch.rs","diffId":"6724","author":"kevincox","id":"43960","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"I would do `self.inner.map(|m| m.is_match(rp)).unwrap_or(false)` but this is fine.","replyTo":null,"isNewFile":"1","line":"200","lineLength":"0","path":"rust\/hgstorage\/src\/matcher.rs","diffId":"6724","author":"kevincox","id":"43959","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"s\/rp\/path\/","replyTo":null,"isNewFile":"1","line":"195","lineLength":"0","path":"rust\/hgstorage\/src\/matcher.rs","diffId":"6724","author":"kevincox","id":"43958","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"s\/relglob\/relative_glob_re\/","replyTo":null,"isNewFile":"1","line":"108","lineLength":"0","path":"rust\/hgstorage\/src\/matcher.rs","diffId":"6724","author":"kevincox","id":"43957","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"Is this a warning or error? You might want to switch to `panic!`.","replyTo":null,"isNewFile":"1","line":"159","lineLength":"0","path":"rust\/hgstorage\/src\/matcher.rs","diffId":"6724","author":"kevincox","id":"43956","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"I would move this into the following match because it dedupes the `starts_with` check and puts the logic closer together.","replyTo":null,"isNewFile":"1","line":"160","lineLength":"0","path":"rust\/hgstorage\/src\/matcher.rs","diffId":"6724","author":"kevincox","id":"43955","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"s\/ln\/line\/","replyTo":null,"isNewFile":"1","line":"143","lineLength":"0","path":"rust\/hgstorage\/src\/matcher.rs","diffId":"6724","author":"kevincox","id":"43954","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"Better name please.","replyTo":null,"isNewFile":"1","line":"131","lineLength":"0","path":"rust\/hgstorage\/src\/matcher.rs","diffId":"6724","author":"kevincox","id":"43953","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"You should be able to do `&string` rather then `string.as_str()` as it coerces. ","replyTo":null,"isNewFile":"1","line":"111","lineLength":"0","path":"rust\/hgstorage\/src\/matcher.rs","diffId":"6724","author":"kevincox","id":"43952","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"If you are just doing one call just return the result.","replyTo":null,"isNewFile":"1","line":"111","lineLength":"0","path":"rust\/hgstorage\/src\/matcher.rs","diffId":"6724","author":"kevincox","id":"43951","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"If you are going to call `String.as_str()` just take a `&str`.","replyTo":null,"isNewFile":"1","line":"108","lineLength":"0","path":"rust\/hgstorage\/src\/matcher.rs","diffId":"6724","author":"kevincox","id":"43950","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"Can you manage a `&[u8]` rather then pointer arithmetic for the whole string. It will make me feel better and will probably be easier to read.","replyTo":null,"isNewFile":"1","line":"14","lineLength":"0","path":"rust\/hgstorage\/src\/matcher.rs","diffId":"6724","author":"kevincox","id":"43949","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"Might be worth calling `String::with_capacity(pat.len())` since it will be at least that long.","replyTo":null,"isNewFile":"1","line":"10","lineLength":"0","path":"rust\/hgstorage\/src\/matcher.rs","diffId":"6724","author":"kevincox","id":"43948","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"s\/pat\/glob\/","replyTo":null,"isNewFile":"1","line":"9","lineLength":"0","path":"rust\/hgstorage\/src\/matcher.rs","diffId":"6724","author":"kevincox","id":"43947","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"What are these numbers?","replyTo":null,"isNewFile":"1","line":"49","lineLength":"0","path":"rust\/hgstorage\/src\/manifest.rs","diffId":"6724","author":"kevincox","id":"43946","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"s\/ent\/entry\/","replyTo":null,"isNewFile":"1","line":"42","lineLength":"0","path":"rust\/hgstorage\/src\/manifest.rs","diffId":"6724","author":"kevincox","id":"43945","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"What are these magic numbers?","replyTo":null,"isNewFile":"1","line":"33","lineLength":"0","path":"rust\/hgstorage\/src\/manifest.rs","diffId":"6724","author":"kevincox","id":"43944","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"This test has no assetions. Consider calling it `test_create_...` or something to indicate that you are just checking for panics.","replyTo":null,"isNewFile":"1","line":"155","lineLength":"0","path":"rust\/hgstorage\/src\/local_repo.rs","diffId":"6724","author":"kevincox","id":"43943","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"Why does it need to be mutable to clone?","replyTo":null,"isNewFile":"1","line":"136","lineLength":"0","path":"rust\/hgstorage\/src\/local_repo.rs","diffId":"6724","author":"kevincox","id":"43942","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"s\/fp\/path\/","replyTo":null,"isNewFile":"1","line":"121","lineLength":"0","path":"rust\/hgstorage\/src\/local_repo.rs","diffId":"6724","author":"kevincox","id":"43941","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"`gd` is cryptic.","replyTo":null,"isNewFile":"1","line":"129","lineLength":"0","path":"rust\/hgstorage\/src\/local_repo.rs","diffId":"6724","author":"kevincox","id":"43940","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"```\nassert!(abspath.exists(), \"path not exists: {:?}\", abspath);\n```","replyTo":null,"isNewFile":"1","line":"127","lineLength":"0","path":"rust\/hgstorage\/src\/local_repo.rs","diffId":"6724","author":"kevincox","id":"43939","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"```\nwhile !root.join(\".hg\").exists() {\n root = root.parent().expect(\".hg folder not found\");\n}\n```","replyTo":null,"isNewFile":"1","line":"66","lineLength":"0","path":"rust\/hgstorage\/src\/local_repo.rs","diffId":"6724","author":"kevincox","id":"43938","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"I would replace the condition with.\n\n```\nassert!(dot_hg_path.exists(), \".hg folder not found for the path given by -R argument: {:?}\", p);\n```","replyTo":null,"isNewFile":"1","line":"50","lineLength":"0","path":"rust\/hgstorage\/src\/local_repo.rs","diffId":"6724","author":"kevincox","id":"43937","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"You can add a later `.arg(dst)` to support non-utf8 paths instead of converting to a str here.","replyTo":null,"isNewFile":"1","line":"54","lineLength":"0","path":"rust\/hgstorage\/src\/lib.rs","diffId":"6724","author":"kevincox","id":"43936","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"In rust we generally avoid brackets around `as` as it is very tightly binding.","replyTo":null,"isNewFile":"1","line":"206","lineLength":"0","path":"rust\/hgstorage\/src\/dirstate.rs","diffId":"6724","author":"kevincox","id":"43935","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"Please use a better name for `sent`.","replyTo":null,"isNewFile":"1","line":"199","lineLength":"0","path":"rust\/hgstorage\/src\/dirstate.rs","diffId":"6724","author":"kevincox","id":"43934","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"You can use the entry api here.","replyTo":null,"isNewFile":"1","line":"184","lineLength":"0","path":"rust\/hgstorage\/src\/dirstate.rs","diffId":"6724","author":"kevincox","id":"43933","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"s\/rem\/path\/ or remaining_path.","replyTo":null,"isNewFile":"1","line":"183","lineLength":"0","path":"rust\/hgstorage\/src\/dirstate.rs","diffId":"6724","author":"kevincox","id":"43932","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"Use an `else if`.","replyTo":null,"isNewFile":"1","line":"175","lineLength":"0","path":"rust\/hgstorage\/src\/dirstate.rs","diffId":"6724","author":"kevincox","id":"43931","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"You could do the following for a slight performance win and save a line.\n\n```\nif let Occupied(entry) = self.dmap.entry(relpath) {\n ...\n}\n```","replyTo":null,"isNewFile":"1","line":"170","lineLength":"0","path":"rust\/hgstorage\/src\/dirstate.rs","diffId":"6724","author":"kevincox","id":"43930","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"I recommend not renaming this. It is confusing.","replyTo":null,"isNewFile":"1","line":"5","lineLength":"0","path":"rust\/hgstorage\/src\/dirstate.rs","diffId":"6724","author":"kevincox","id":"43929","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"This could have a better name.","replyTo":null,"isNewFile":"1","line":"48","lineLength":"0","path":"rust\/hgstorage\/src\/dirstate.rs","diffId":"6724","author":"kevincox","id":"43928","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"```\nlet mut grey = Set::new();\ngrey.extend(self.dmap.keys().map(|s| s.as_path()));\n```\n\nAlso I would pick a name like `undiscovered_paths` or something. `grey` is cryptic.","replyTo":null,"isNewFile":"1","line":"146","lineLength":"0","path":"rust\/hgstorage\/src\/dirstate.rs","diffId":"6724","author":"kevincox","id":"43927","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"I would also put this filter above. But more importantly all `_is_bad()` does is check for file types. So it seems like the former filter is redundant with this one.","replyTo":null,"isNewFile":"1","line":"169","lineLength":"0","path":"rust\/hgstorage\/src\/dirstate.rs","diffId":"6724","author":"kevincox","id":"43926","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"I would move this filter beside the filter in the loop.","replyTo":null,"isNewFile":"1","line":"167","lineLength":"0","path":"rust\/hgstorage\/src\/dirstate.rs","diffId":"6724","author":"kevincox","id":"43925","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"I would just call this `path` or `pathbuf`.","replyTo":null,"isNewFile":"1","line":"162","lineLength":"0","path":"rust\/hgstorage\/src\/dirstate.rs","diffId":"6724","author":"kevincox","id":"43924","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"Please explain why you are ignoring the error condition.","replyTo":null,"isNewFile":"1","line":"161","lineLength":"0","path":"rust\/hgstorage\/src\/dirstate.rs","diffId":"6724","author":"kevincox","id":"43923","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"This is probably worth a helper function.","replyTo":null,"isNewFile":"1","line":"155","lineLength":"0","path":"rust\/hgstorage\/src\/dirstate.rs","diffId":"6724","author":"kevincox","id":"43922","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"I would prefer doing the filter before the loop and storing it in a variable.","replyTo":null,"isNewFile":"1","line":"152","lineLength":"0","path":"rust\/hgstorage\/src\/dirstate.rs","diffId":"6724","author":"kevincox","id":"43921","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"s\/mtc\/matcher\/","replyTo":null,"isNewFile":"1","line":"141","lineLength":"0","path":"rust\/hgstorage\/src\/dirstate.rs","diffId":"6724","author":"kevincox","id":"43920","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"Don't use `_` prefix for privates. Rely on rust viability. \n\nAlso `is_bad` isn't very informative.","replyTo":null,"isNewFile":"1","line":"130","lineLength":"0","path":"rust\/hgstorage\/src\/dirstate.rs","diffId":"6724","author":"kevincox","id":"43919","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"Is ignoring duplicate entries desired? It might be worth a comment explaining why.","replyTo":null,"isNewFile":"1","line":"125","lineLength":"0","path":"rust\/hgstorage\/src\/dirstate.rs","diffId":"6724","author":"kevincox","id":"43918","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"This should Probably return a `Result<Self>` and pass the error to the caller.","replyTo":null,"isNewFile":"1","line":"87","lineLength":"0","path":"rust\/hgstorage\/src\/dirstate.rs","diffId":"6724","author":"kevincox","id":"43917","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"1. Does this function need to be public? It seems internal to the constructor.\n1. If it doesn't need to be I would prefer it return the Map so that you don't have a partial-constructed DirState.","replyTo":null,"isNewFile":"1","line":"108","lineLength":"0","path":"rust\/hgstorage\/src\/dirstate.rs","diffId":"6724","author":"kevincox","id":"43916","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"I would skip this check and rely on `p.metadata()`. Just switch `.unwrap()` to `.expect()` with a nicer message. This also handles race conditions more nicely.","replyTo":null,"isNewFile":"1","line":"90","lineLength":"0","path":"rust\/hgstorage\/src\/dirstate.rs","diffId":"6724","author":"kevincox","id":"43915","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"Is this used yet? It probably also needs some documentation because I don't really understand the fields (but I do have little domain knowledge).","replyTo":null,"isNewFile":"1","line":"49","lineLength":"0","path":"rust\/hgstorage\/src\/config.rs","diffId":"6724","author":"kevincox","id":"43914","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"If you are just going to convert to String I would recommend taking a String argument.\n\nAlso prefer `.to_owned()` over `.to_string()`.","replyTo":null,"isNewFile":"1","line":"78","lineLength":"0","path":"rust\/hgstorage\/src\/config.rs","diffId":"6724","author":"kevincox","id":"43913","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"Just put `msg: content` in the struct construction.","replyTo":null,"isNewFile":"1","line":"33","lineLength":"0","path":"rust\/hgstorage\/src\/changelog.rs","diffId":"6724","author":"kevincox","id":"43912","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"If you aren't using the value I would prefer `truncate(NodeId::hex_len())`","replyTo":null,"isNewFile":"1","line":"31","lineLength":"0","path":"rust\/hgstorage\/src\/changelog.rs","diffId":"6724","author":"kevincox","id":"43911","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"Passing a message as a third argument is really useful.","replyTo":null,"isNewFile":"1","line":"24","lineLength":"0","path":"rust\/hgstorage\/src\/changelog.rs","diffId":"6724","author":"kevincox","id":"43910","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"Let rust do the overflow checking.\n\n```\nacc = acc.checked_mul(85)\n .ok_or_else(|| {\n PyErr::new::<exc::ValueError, _>(\n py,\n format!(\"bad base85 character at position {}\", i))\n })?;","replyTo":null,"isNewFile":"1","line":"152","lineLength":"0","path":"rust\/hgbase85\/src\/base85.rs","diffId":"6724","author":"kevincox","id":"43909","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"This is probably worth a comment that this is safe because D85DEC is required to be initialized before this function is called.","replyTo":null,"isNewFile":"1","line":"91","lineLength":"0","path":"rust\/hgbase85\/src\/base85.rs","diffId":"6724","author":"kevincox","id":"43908","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"```while !ptext.is_empty()```","replyTo":null,"isNewFile":"1","line":"52","lineLength":"0","path":"rust\/hgbase85\/src\/base85.rs","diffId":"6724","author":"kevincox","id":"43907","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"It might be best to use a [[ https:\/\/doc.rust-lang.org\/stable\/std\/io\/struct.Cursor.html | `std::io::Cursor` ]] and let it drack `dst_off` for your.","replyTo":null,"isNewFile":"1","line":"47","lineLength":"0","path":"rust\/hgbase85\/src\/base85.rs","diffId":"6724","author":"kevincox","id":"43906","dateCreated":"1520530210","dateModified":"1520530210"},{"type":"inline","comment":"`ptext` isn't very descriptive. ","replyTo":null,"isNewFile":"1","line":"45","lineLength":"0","path":"rust\/hgbase85\/src\/base85.rs","diffId":"6724","author":"kevincox","id":"43905","dateCreated":"1520530209","dateModified":"1520530209"},{"type":"inline","comment":"Tracking len manually is a smell. Why not drop it and use `ptest.is_empty()`.","replyTo":null,"isNewFile":"1","line":"63","lineLength":"0","path":"rust\/hgbase85\/src\/base85.rs","diffId":"6724","author":"kevincox","id":"43904","dateCreated":"1520530209","dateModified":"1520530209"},{"type":"inline","comment":"I would prefer the name `chunk` or even `accum` is a lot mode obvious to me than `acc`.","replyTo":null,"isNewFile":"1","line":"54","lineLength":"0","path":"rust\/hgbase85\/src\/base85.rs","diffId":"6724","author":"kevincox","id":"43903","dateCreated":"1520530209","dateModified":"1520530209"},{"type":"inline","comment":"I suspect this type annotation isn't required.","replyTo":null,"isNewFile":"1","line":"47","lineLength":"0","path":"rust\/hgbase85\/src\/base85.rs","diffId":"6724","author":"kevincox","id":"43902","dateCreated":"1520530209","dateModified":"1520530209"},{"type":"inline","comment":"Why the braces here?","replyTo":null,"isNewFile":"1","line":"46","lineLength":"0","path":"rust\/hgbase85\/src\/base85.rs","diffId":"6724","author":"kevincox","id":"43901","dateCreated":"1520530209","dateModified":"1520530209"},{"type":"inline","comment":"IIUC pad is only ever checked `== 0`. Can it be made into a bool?","replyTo":null,"isNewFile":"1","line":"23","lineLength":"0","path":"rust\/hgbase85\/src\/base85.rs","diffId":"6724","author":"kevincox","id":"43900","dateCreated":"1520530209","dateModified":"1520530209"},{"type":"inline","comment":"I would just combine these into one line as the name `ch` isn't adding much.","replyTo":null,"isNewFile":"1","line":"58","lineLength":"0","path":"rust\/hgbase85\/src\/base85.rs","diffId":"6724","author":"kevincox","id":"43899","dateCreated":"1520530209","dateModified":"1520530209"},{"type":"inline","comment":"`&str` can only hold valid utf8 data? Does it make more sense to have `&[u8]` here for a list of bytes?","replyTo":null,"isNewFile":"1","line":"23","lineLength":"0","path":"rust\/hgbase85\/src\/base85.rs","diffId":"6724","author":"kevincox","id":"43898","dateCreated":"1520530209","dateModified":"1520530209"},{"type":"inline","comment":"Would it be possible to separate the decode from the python objects. I'm thinking two helper functions.\n\n```\nfn b85_required_len(text: &str) -> usize\nfn b85_encode(text: &str, pad: i32, out: &mut [u8]) -> Result<()>\n```\n\n","replyTo":null,"isNewFile":"1","line":"23","lineLength":"0","path":"rust\/hgbase85\/src\/base85.rs","diffId":"6724","author":"kevincox","id":"43897","dateCreated":"1520530209","dateModified":"1520530209"},{"type":"inline","comment":"```\nfor i in &[24, 16, 8, 0]\n```","replyTo":null,"isNewFile":"1","line":"56","lineLength":"0","path":"rust\/hgbase85\/src\/base85.rs","diffId":"6724","author":"kevincox","id":"43896","dateCreated":"1520530209","dateModified":"1520530209"},{"type":"inline","comment":"I prefer something like this: https:\/\/play.rust-lang.org\/?gist=5ca18a5b95335600e911b8f9310ea5c7&version=stable\n\nI doubt lazy_static is too slow. Otherwise we can stay like this until const functions get implemented.\n\nEither way note:\n* I changed the type of B85CHARS to an array as opposed to an array ref.\n* The loop condition is much nicer.","replyTo":null,"isNewFile":"1","line":"21","lineLength":"0","path":"rust\/hgbase85\/src\/base85.rs","diffId":"6724","author":"kevincox","id":"43895","dateCreated":"1520530209","dateModified":"1520530209"},{"type":"inline","comment":"If this is going to be reused I would move it into it's own crate. It seems like everything here could be boiled down to a single function call in main.","replyTo":"43863","isNewFile":"1","line":"1","lineLength":"0","path":"rust\/hgbase85\/build.rs","diffId":"6724","author":"kevincox","id":"43894","dateCreated":"1520530209","dateModified":"1520530209"},{"type":"comment","comment":"I will try to finish the review later, but it might be quicker if you incorporate some of the changes first since a lot of them are repeated many times. Overall it looks good, there are a couple of things that i would highlight to make the code easier to read.\n\n* Prefer more descriptive variable names.\n* If you can, avoid \"pointer\" arithmetic. Cursors and slices are nice and have great convenience methods.\n* Group your flow control and filtering more.\n* Try to keep your types straight. In rust using the right types helps catch errors. So be aware of `char` vs `u8` vs `String` vs `Vec<char>` vs `Vec<u8>`.\n\nOn a higher level, all of these code appears to be treating file names as strings. This isn't really true and will disallow some valid file names. Maybe we should stick with bytes throughout. Of course this makes windows filepaths difficult because they are actually (utf16) strings.","author":"kevincox","id":"43893","dateCreated":"1520530209","dateModified":"1520530209"},{"type":"reject","author":"kevincox","id":"43892","dateCreated":"1520530209","dateModified":"1520530209"},{"type":"comment","comment":"Doesn't mononoke have code to read revlogs already?","author":"glandium","id":"43869","dateCreated":"1520495348","dateModified":"1520495348"},{"type":"inline","comment":"IIRC, core Mercurial keeps an open file handle on revlogs and ensures we don't run out of file handles by not keeping too many revlogs open at the same time. For scanning operations, not having to open and close the file handles all the time will make a difference for performance. Also, core Mercurial loads the entirety of the `.i` file into memory. That's a scaling problem for large revlogs. But it does make performance of index lookups really fast.","replyTo":null,"isNewFile":"1","line":"279","lineLength":"0","path":"rust\/hgstorage\/src\/revlog_v1.rs","diffId":"6724","author":"indygreg","id":"43867","dateCreated":"1520494272","dateModified":"1520494272"},{"type":"inline","comment":"A thread pool to help with zlib decompression should go a long way here.\n\nProbably too early to think about this, but we'll likely eventually want a global thread pool for doing I\/O and CPU expensive tasks, such as reading chunks from a revlog and decompressing them.\n\nFWIW, we're going to radically alter the storage format in order to better support shallow clones. But that work hasn't started yet. I still think there is a benefit to implementing the revlog code in Rust though.","replyTo":null,"isNewFile":"1","line":"290","lineLength":"3","path":"rust\/hgstorage\/src\/revlog_v1.rs","diffId":"6724","author":"indygreg","id":"43866","dateCreated":"1520494272","dateModified":"1520494272"},{"type":"inline","comment":"I would not worry about supporting v0 or v2 at this time. v0 is only important for backwards compatibility with ancient repos. And v2 never got off the ground.","replyTo":null,"isNewFile":"1","line":"95","lineLength":"0","path":"rust\/hgstorage\/src\/config.rs","diffId":"6724","author":"indygreg","id":"43865","dateCreated":"1520494272","dateModified":"1520494272"},{"type":"inline","comment":"This is definitely nifty and an impressive achievement \\o\/\n\nThe `r-` commands for testing pure Rust code paths are an interesting idea!\n\nI think I'm OK with including support for this in `hgcli`. But I think the code should live in a separate file so it doesn't pollute `main()`. And it should be behind a Cargo feature flag so we maintain compatibility with `hg` as much as possible by default.\n\nAlso, Mercurial's command line parser is extremely wonky and has some questionable behavior. If the intent is to make `rhg` compatible with `hg`, we would need to preserve this horrible behavior. We'll likely have to write a custom argument parser because of how quirky Mercurial's argument parser is :(","replyTo":null,"isNewFile":"1","line":"233","lineLength":"28","path":"rust\/hgcli\/src\/main.rs","diffId":"6724","author":"indygreg","id":"43864","dateCreated":"1520494272","dateModified":"1520494272"},{"type":"inline","comment":"I see this file was copied. There's nothing wrong with that. But does this mean we will need a custom build.rs for each Rust package doing Python? If that's the case, then I would prefer to isolate all our rust-cpython code to a single package, if possible. I'm guessing that could be challenging due to crossing create boundaries. I'm sure there are placed where we don't want to expose symbols outside the crate.\n\nI'm curious how others feel about this.","replyTo":null,"isNewFile":"1","line":"1","lineLength":"0","path":"rust\/hgbase85\/build.rs","diffId":"6724","author":"indygreg","id":"43863","dateCreated":"1520494272","dateModified":"1520494272"},{"type":"comment","comment":"First of all - wow! Thanks for writing all this code. There's definitely a lot to work with. And work with it we will!\n\nThis is definitely too big to review as one commit. If you could do *any* work to split it up, it would be greatly appreciated. I'd focus on the pure Rust pieces first. Everything needed to open revlogs would be great!\n\nYou may find our custom Phabricator extensions (linked from https:\/\/www.mercurial-scm.org\/wiki\/Phabricator) useful for submitting series of commits to Phabricator.\n\nRegarding the performance, that's pretty good! The dirstate code is some of the most optimized code in Mercurial. There are some gnarly Python C hacks to make it fast. Some of those tricks involve using special system calls to walk directories to minimize the number of system calls. I'm not sure if the crate you imported has those optimizations. (I wouldn't be surprised either way.) I wouldn't worry too much about performance at this juncture. But I suspect we could make the Rust code another 50% faster with some tweaking. It would also be interesting to test on a larger repo, say https:\/\/hg.mozilla.org\/mozilla-unified. Also, I believe there are hooks in the dirstate code to use Watchman (fsmonitor). Those hooks are critical in order to achieve peak performance on large repositories.\n\nSince you seem to be proficient at writing lots of Rust code, if you are looking for another project, may I suggest porting `chg` to Rust? That code is in `contrib\/chg`. That might be the easiest component to actually ship in Rust since it is a standalone binary that doesn't link against Python. But we shouldn't get ahead of ourselves :)\n\nAnyway, it is late for me and I need to detach from my computer. I'm sure others will have things to say as well...","author":"indygreg","id":"43862","dateCreated":"1520494272","dateModified":"1520494272"},{"type":"comment","comment":"Hi all,\n\nBased on the discussion a few weeks ago, I come up with a solution for review and discussion. After reading the Oxidation plan, the first thought is to bypass python engine and current plugin system IFF on request. If user (maybe background checker of IDE) request r-* subcommands, then hg gives rust implementations instead of python's. So I try to make hg r-status as fast as possible. The submitted version has comparable performance (as an example of the performance, not evidence, on my MacBook, in hg's own repo, hg r-status 150ms, and hg status 220ms). I am using CodeXL to profile the performance, and plan to use Future.rs to make the loading parallel and maybe 30ms faster.\n\nThe implementation originates from hg python implementation, because the python version is really fast. I tried to split into small changes, however, I eventually to combine all hgstorage module as one commit.\n\nThank you for your comments!","author":"Ivzhh","id":"43861","dateCreated":"1520491361","dateModified":"1520491361"},{"type":"comment","comment":" - merge with stable\n - translate base85.c into rust code\n - move hgbase85 into independent module\n - add hgstorage crate\n - hg status implementation in rust\n","author":"Ivzhh","id":"43856","dateCreated":"1520490633","dateModified":"1520490633"},{"type":"update","diffId":"6724","author":"Ivzhh","id":"43855","dateCreated":"1520490633","dateModified":"1520490633"},{"type":"comment","comment":"Thank you @indygreg!\n\nThe OxidationPlan is my best reference when I started to make a move, and this thread is even more helpful. I am really interested in exploring this ;-) In 2014 I was trying to change the hg backend storage to Postgres, a silly and failed experiment.\n\nAnyway, I will save everyone's time and stop talking. I will come back later with a more meaningful implementation.","author":"Ivzhh","id":"34977","dateCreated":"1518075333","dateModified":"1518075333"},{"type":"comment","comment":"To be honest, we're not yet sure what we'll decide for the Python -> Rust bridge. The problem is summarized in the `Rust <=> Python Interop` section on https:\/\/www.mercurial-scm.org\/wiki\/OxidationPlan.\n\nI suspect at some level we'll need a CPython extension for CPython for performance reasons (especially for high volume function calls). PyPy obviously uses CFFI. I think the ideal outcome is we can write Rust that exposes a C API and use CFFI natively on PyPy and something like `cbindgen` + `Milksnake` to auto-generate a CPython extension that acts as a wrapper around the C API exposed by Rust. I'm not sure if anyone has invented this exact wheel yet. If not, it's probably faster to use `rust-cpython`. Maybe several months from now we have enough Rust and maintaining `rust-cpython` is painful enough that we pursue the auto-generated CPython extension route.\n\nWhat I'm trying to say is you have a green field to explore! But at this juncture, perfect is the enemy of done. We'll be happy with any forward progress, even failed experiments.","author":"indygreg","id":"34976","dateCreated":"1518074550","dateModified":"1518074550"},{"type":"comment","comment":"As the author of this patch, actually I have the same concern. I started to translate base85 as baby steps to find a way of integrating rust and cpython, on my side, Today I modify setup.py, policy.py and makefile to run hg's test suit with the new base85. For myself, it is only proof of concept.\n\nMaybe I should take another way: translate more python modules into CFFI-style, and let CFFI call rust implementation. And gradually change more implementations of python modules with corresponding cffi-style, while keep the python interface the same. My own hope is the rust routines will be able to call each other and eventually run some __basic__ tasks without calling python part. And the rust still lazily provides info to python interface for extensions etc.\n\nI am exploring this way now, and hope the findings will be useful for community to make decision.\n\nThank you all for the comments!","author":"Ivzhh","id":"34975","dateCreated":"1518070365","dateModified":"1518070365"},{"type":"comment","comment":"What would be the advantage of taking this? Since we already have the C implementation, it's not likely to gain us any performance. On the other hand, it might make a good test case for integrating Rust and Python, finding the right API boundaries and experimenting with different approaches, precisely \/\/because\/\/ we already have a C implementation. @indygreg @durin42 what are your thoughts about it?\n\n","author":"krbullock","id":"34910","dateCreated":"1518062354","dateModified":"1518062354"},{"type":"comment","comment":"I agree with the splitting comments :) In fact there might already be a base85 crate which can be used: https:\/\/docs.rs\/zero85. Either way I'll hold off on the review, feel free to ping me when you are ready for me to take a look.","author":"kevincox","id":"34640","dateCreated":"1518001891","dateModified":"1518001891"},{"type":"comment","comment":"Thank you @indygreg for your detailed explanation!\n\nI understand the process now, and I will go back reading the developer's guide thoroughly again. I will try my best to provide a relatively clean stack of patches.\n\nThank you for you time!","author":"Ivzhh","id":"34561","dateCreated":"1517972031","dateModified":"1517972031"},{"type":"comment","comment":"We generally prefer that patches to Mercurial be small and do a single thing. This makes it easier to review and understand changes, since each change can be evaluated in isolation. If you submit changesets together using `hg phabsend`, they automatically show up as a \/\/stack\/\/ in Phabricator. And if changesets at the bottom of the stack are ready to land, we generally land those without waiting for the entire stack to land. This enables forward progress to be made and this is generally better for everyone than waiting until a series of commits is perfect before adding any of them.\n\nWhat that means is you should ideally split this work into smaller parts. For example:\n\n # Add the pure Rust code\/crate\n # Add the Python Rust code\/crate\n # Build system \/ module policy changes\n\nI'm not sure of the order of things though. Since this is the first Rust extension, it's not clear what needs to be implemented in what order. I'm fine looking at a large commit if things are too tightly coupled to separate. But you should strive to make smaller commits.\n\n","author":"indygreg","id":"34557","dateCreated":"1517970792","dateModified":"1517970792"},{"type":"comment","comment":"Sure, thank you for the comments! I can definitely prepare makefile and setup.py to make the building process work with rust part. I am planning to change the policy.py module to support and try to load rust modules and run all the tests. I will submit a new patch after finishing these two tasks.\n\nAfter reading wiki\/OxidationPlan again, I plan to change to cffi for better compatibility (pypy and others), and try to build algorithms in pure rust. Shall I wait till migrating to cffi based solution now and resubmit this patch with all three changes (building, testing, and cffi)?\n\nThank you!","author":"Ivzhh","id":"34556","dateCreated":"1517970271","dateModified":"1517970271"},{"type":"comment","comment":"Yes, we should definitely split things into multiple crates. Small, narrowly-focused crates does seem to be the Rust way, after all.\n\n`hgcli` should be for things specific to the Rust implementation of `hg`. I think this can also include the feature set of `chg` (once we've ported `chg` to Rust).\n\nI definitely support separating the \"pure Rust\" from the \"Python Rust\" via a crate boundary. It is generally useful to have Rust that isn't bound to Python because it will facilitate reuse outside of Python contexts. For example, someone could implement a Mercurial wire protocol server in pure Rust without needing to worry about Python. Of course, we're likely to encounter areas where we really want tight coupling in order to achieve optimal performance in Python. So we may have to design APIs on the pure Rust side to facilitate CPython use. I'm OK with that.\n\nAs for how many crates to have, I don't have super strong opinions. I could see us putting every little component\/subsystem in its own crate. I could also see us putting everything in one large crate. I don't think it is worth deciding at this early juncture. API design and ability to be reused outside its originally intended purpose is the important property to strive for. I think that has more to do with how the code is authored rather than which crates things are in.\n\nA missing piece of this patch is the build system and module loader integration. We have a \/\/module policy\/\/ that dictates which implementation of a Python module we use. We probably want to introduce a `rust` policy that uses Rust-based modules where available and falls back to the `cext` modules\/policy if a Rust module isn't available. We also need to figure out how to integrate Rust into `setup.py`. But I think the build system bit can be deferred until we're actually ready to ship Rust, which is still a bit of ways off. I'm happy for the workflow to be \/\/run cargo in order to load Rust modules\/\/ for the time being. But if you can implement `Makefile` and\/or `setup.py` integration to build these Rust extensions, that would be awesome.","author":"indygreg","id":"34484","dateCreated":"1517947275","dateModified":"1517947275"},{"type":"comment","comment":"I am open to the three-crates plan. Oirginally I have hgcli and hgext separately, and I was planning to use CFFI mode. I am a pypy user too, so I will be willing to provide a python C API free crate for pypy and others.","author":"Ivzhh","id":"34443","dateCreated":"1517928889","dateModified":"1517944524"},{"type":"inline","comment":"I think I'd like to separate things a bit more and have a Python-free module, and then a glue module that we can use to call into the pure Rust. Part of the reason is that in my perfect world we won't use the cpython crate for speedups so they can be used from pypy as well. Separating them at least makes it easier to have an extern \"C\" version of the method that can be used from cffi instead of only through the CPython API.\n\n(Not sure what opinions others have. It's likely that I'll attempt this approach in the near future as part of a continued attempt to speed up `hg diff`.)","replyTo":null,"isNewFile":"1","line":"22","lineLength":"0","path":"rust\/hgcli\/src\/hgext\/base85.rs","diffId":"5238","author":"durin42","id":"34390","dateCreated":"1517913293","dateModified":"1517913293"},{"type":"comment","comment":"I'd be curious to see what @indygreg has to say about this, maybe wait on his input before doing any work in response to my feedback?\n\nI do wonder if we should have at least three crates:\n\n # hgcli\n # libmercurial\n # hgcext\n\nThe first one would be the command-line entry point, the last could use the cpython API, and libmercurial would be \"pure rust\" and open the door to eventually having a libhg or something that exports C functions and would be suitable for cffi and linking into other binaries?","author":"durin42","id":"34389","dateCreated":"1517913293","dateModified":"1517913293"},{"type":"update","diffId":"5238","author":"Ivzhh","id":"34367","dateCreated":"1517869861","dateModified":"1517869861"}],"dateCreated":"1517869861","dateModified":"1579887188","status":"Needs Revision"},{"id":"2623","callsign":"HG","title":"dispatch: adding config items for overriding flag defaults","author":"rdamazio","summary":"This introduces the new defaults format \"commandname.default.optionname\" which\ndirectly overrides the default of the option, instead of prepending the\ncommand-line option. This is meant to replace the [defaults] section which is\nalready deprecated in a manner that's easier and safer to use than creating\naliases.","testPlan":"","lineCount":"96","dependsOn":["2622"],"reviewers":["yuja","baymax"],"ccs":["dploch","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117697","dateCreated":"1579887186","dateModified":"1579887186"},{"type":"reject","author":"baymax","id":"117696","dateCreated":"1579887186","dateModified":"1579887186"},{"type":"inline","comment":"I thought callables were meant to be used to generate the default default, not with overridden values?","replyTo":"43409","isNewFile":"1","line":"625","lineLength":"1","path":"mercurial\/dispatch.py","diffId":"6609","author":"rdamazio","id":"47743","dateCreated":"1522132208","dateModified":"1522132208"},{"type":"inline","comment":"Nobody should use the same *instance* on multiple flags. Even with the current flags, if you use e.g. the same list on many, that'll cause problems with listopt.\n","replyTo":"43410","isNewFile":"1","line":"639","lineLength":"1","path":"mercurial\/dispatch.py","diffId":"6609","author":"rdamazio","id":"47742","dateCreated":"1522132208","dateModified":"1522132208"},{"type":"inline","comment":"This makes me nervous. What if someone re-uses a customopt instance in multiple commands? i.e.:\n\nDATE_FLAG = mypkg.dateopt()\n...\n('b', 'before', DATE_FLAG, '')\n('a', 'after', 'DATE_FLAG', '')\n\nNow, setting commands.defaults.before=2018-03-05 also silently changes the default for 'after'. I suspect we need to introduce a wrapper class like what I suggest on lines 625-625, that delegates and leaves the original default unchanged. And either way, we should probably clarify in the docs on customopts what expected use of the class is (i.e., should we just forbid reuse, is 'oldstate' safe to mutate, etc.)","replyTo":null,"isNewFile":"1","line":"639","lineLength":"1","path":"mercurial\/dispatch.py","diffId":"6609","author":"dploch","id":"43410","dateCreated":"1520292544","dateModified":"1520292544"},{"type":"inline","comment":"This doesn't handle callables properly. I wonder if the something like the following would work instead:\n\noldopt = fancyopts._defaultopt(olddefault)\nnewdefault = old.opt.newstate(olddefault, ui.config(\"commands\", cfgitem)\nc[idx] = (opt[0], opt[1], fancyopts._withnewdefault(oldopt, newdefault), opt[3])\n\nWhere '_withnewdefault' is a wrapper customopt that just changes the default.","replyTo":null,"isNewFile":"1","line":"625","lineLength":"1","path":"mercurial\/dispatch.py","diffId":"6609","author":"dploch","id":"43409","dateCreated":"1520292544","dateModified":"1520292544"},{"type":"inline","comment":"I think rdamazio's response is correct. The type information for an opt exists only in the 'defaultvalue' slot in the tuple, so it needs to be extracted from there before reading the config. I don't have a strong opinion as to where this code should go - 'ui' does seem marginally more appropriate than 'fancyopts', since it keeps 'fancyopts' low-level and not depending on 'ui'.","replyTo":"42582","isNewFile":"1","line":"624","lineLength":"0","path":"mercurial\/dispatch.py","diffId":"6523","author":"dploch","id":"43408","dateCreated":"1520292544","dateModified":"1520292544"},{"type":"inline","comment":"Ah, makes sense. See if this addresses that case satisfactorily - it still has the caveat of not being able to \"reset\" container types, but that's true of the command line as well (if you have a list flag with a non-empty default, there's no way to remove that default item).","replyTo":"42770","isNewFile":"1","line":"624","lineLength":"0","path":"mercurial\/dispatch.py","diffId":"6523","author":"rdamazio","id":"43071","dateCreated":"1520195950","dateModified":"1520195950"},{"type":"update","diffId":"6609","author":"rdamazio","id":"43064","dateCreated":"1520195818","dateModified":"1520195818"},{"type":"inline","comment":"IIUC, an extension author may implement its own customopt subclasses, and\nput them into the command table, so we can't make ui.configtyped to\nsupport all of them.","replyTo":"42686","isNewFile":"1","line":"624","lineLength":"0","path":"mercurial\/dispatch.py","diffId":"6523","author":"yuja","id":"42770","dateCreated":"1520183736","dateModified":"1520183736"},{"type":"inline","comment":"You're right, I had the plain logic inverted in my head. Removed.","replyTo":"42581","isNewFile":"1","line":"390","lineLength":"0","path":"mercurial\/ui.py","diffId":"6523","author":"rdamazio","id":"42687","dateCreated":"1520181261","dateModified":"1520181261"},{"type":"inline","comment":"The issue is that customopt (and all its children) assume the value type is already the correct one, and thus do not perform any conversion. Since we're parsing values from the config file, the conversion is desired to ensure they don't all end up as text - the config{bool,int,etc} methods called by configtyped perform the proper conversion. In most cases (all commands that declare default values) no conversio is needed since those already have the correct type.\n","replyTo":"42582","isNewFile":"1","line":"624","lineLength":"0","path":"mercurial\/dispatch.py","diffId":"6523","author":"rdamazio","id":"42686","dateCreated":"1520181261","dateModified":"1520181261"},{"type":"update","diffId":"6548","author":"rdamazio","id":"42684","dateCreated":"1520181250","dateModified":"1520181250"},{"type":"inline","comment":"Maybe this type conversion can be a `fancyopt.customopt` method since we've\nrefactored the default handling by D2090?\n\n```\n# no idea if _defaultopt() should be made public or the whole commands.default handling\n# should be moved to fancyopts\nx = fancyopts._defaultopt(olddefault)\nnewdefault = x.configdefault(ui, cmd, optname, ...)\n```\n\n@dploch, any suggestions?","replyTo":null,"isNewFile":"1","line":"624","lineLength":"0","path":"mercurial\/dispatch.py","diffId":"6523","author":"yuja","id":"42582","dateCreated":"1520173297","dateModified":"1520173297"},{"type":"inline","comment":"Perhaps this is noop since `[commands]` is removed at all if `ui.plain()` returns True.","replyTo":null,"isNewFile":"1","line":"390","lineLength":"0","path":"mercurial\/ui.py","diffId":"6523","author":"yuja","id":"42581","dateCreated":"1520173297","dateModified":"1520173297"},{"type":"reject","author":"yuja","id":"42578","dateCreated":"1520173297","dateModified":"1520173297"},{"type":"comment","comment":"FYI this is a change I had previously sent to the list as 60b3222e01f96f91ece7eda9681a89bf3bb930a6, and Yuya reviewed . I just had never followed up on it.","author":"rdamazio","id":"42436","dateCreated":"1520122245","dateModified":"1520122245"},{"type":"update","diffId":"6523","author":"rdamazio","id":"42435","dateCreated":"1520121514","dateModified":"1520121514"},{"type":"update","diffId":"6521","author":"rdamazio","id":"42421","dateCreated":"1520121282","dateModified":"1520121282"}],"dateCreated":"1520121282","dateModified":"1579887186","status":"Needs Revision"},{"id":"3663","callsign":"HG","title":"graft: add test showing --continue not preserving --edit passed earlier","author":"pulkit","summary":"Right now, if you run `hg graft --edit`, face some conflicts, resolve them and\nthen run `hg graft --continue`, you will see graft no longer pops up for the\neditor and you hate mercurial for not remembering arguments you passed earlier.\n\nUpcoming patch will fix this buggy behavior and this test will help us in\nrealizing those changes.","testPlan":"","lineCount":"41","dependsOn":[],"reviewers":["baymax"],"ccs":["mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117694","dateCreated":"1579887185","dateModified":"1579887185"},{"type":"reject","author":"baymax","id":"117693","dateCreated":"1579887185","dateModified":"1579887185"},{"type":"update","diffId":"8908","author":"pulkit","id":"57562","dateCreated":"1527287120","dateModified":"1527287120"}],"dateCreated":"1527287120","dateModified":"1579887185","status":"Needs Revision"},{"id":"3187","callsign":"HG","title":"phase: add dry-run functionality","author":"khanchi97","summary":"Added the logic to find those csets whose phase will be changed\n(while running without --dry-run). And show the list of those csets.","testPlan":"","lineCount":"173","dependsOn":[],"reviewers":["pulkit","baymax"],"ccs":["av6","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117691","dateCreated":"1579887184","dateModified":"1579887184"},{"type":"reject","author":"baymax","id":"117690","dateCreated":"1579887184","dateModified":"1579887184"},{"type":"update","diffId":"8962","author":"khanchi97","id":"57894","dateCreated":"1528037274","dateModified":"1528037274"},{"type":"comment","comment":"Nice work! I like where how you simplified things from previous version.\n\nIf you look at the patch, this seems to do multiple things at once which are:\n\n * adding dry-run argument to advanceboundary and retractboundary functions\n * adding a new --dry-run flag to hg phase\n\nLet's break things up in individual patches so that we can improve more on individual pieces. Can you split this into a separate patch for adding dryrun argument to each function, i.e. one patch for adcanceboundary, one for retractboundary, and then one last patch which adds the new flag? That will be very much helpful in reviewing this work and also making incremental changes and moving forward step by step.","author":"pulkit","id":"57621","dateCreated":"1527622549","dateModified":"1527622549"},{"type":"comment","comment":"@pulkit Now I moved the logic for finding revs (those phase will change) to advanceboundry and retractboundry function and for now it shows all nodes. I am working to show range instead. Take a look at this when you are free :)","author":"khanchi97","id":"57619","dateCreated":"1527584154","dateModified":"1527584154"},{"type":"update","diffId":"8896","author":"khanchi97","id":"57476","dateCreated":"1527280427","dateModified":"1527280427"},{"type":"comment","comment":">>! In D3187#57349, @khanchi97 wrote:\n> okay, but I have some queries like\n> 1. How about showing revision no. instead of cset id?\n\nI think we should show cset ids. If you want to with rev numbers, go with that. This should not be a blocker to get the initial patch in.\n> 2. And in this https:\/\/pastebin.com\/raw\/kWcr9xVK example if I change revision 2 phase to --secret then how it should print the range, I mean now we have branches in this range?\n> \n> Can we show that range like this:\n> \n> 0316ce92851d : : b385d13d5ed4 draft -> secret\n> 0316ce92851d : : 4ccc844d5454 draft -> secret\n\nThere are two ways you can show the range in this case:\n\n1) 0316ce92851d::b385d13d5ed4 and f19b7f89f44e::4ccc844d5454\n2) 0316ce92851d::4ccc844d5454 and b385d13d5ed4\n\nLook into `hg help revsets` to understand what `::` means.","author":"pulkit","id":"57419","dateCreated":"1527196739","dateModified":"1527196739"},{"type":"comment","comment":"okay, but I have some queries like\n1. How about showing revision no. instead of cset id?\n2. And in this https:\/\/pastebin.com\/raw\/kWcr9xVK example if I change revision 2 phase to --secret then how it should print the range, I mean now we have branches in this range?\n\nCan we show that range like this:\n\n0316ce92851d : : b385d13d5ed4 draft -> secret\n0316ce92851d : : 4ccc844d5454 draft -> secret","author":"khanchi97","id":"57349","dateCreated":"1527158527","dateModified":"1527158527"},{"type":"inline","comment":"This is not very much helpful. In such cases, how about showing the range of changesets, something like:\n```f7b1eb17ad24::925d80f479bb public -> draft\nb385d13d5ed4::fdc0253c25cf secret -> draft``` ","replyTo":null,"isNewFile":"1","line":"990","lineLength":"0","path":"tests\/test-phases.t","diffId":"7877","author":"pulkit","id":"57180","dateCreated":"1526844970","dateModified":"1526844970"},{"type":"inline","comment":"Since all the logic is copy-pasted from phases.advanceboundary and phases.retractboundary, why not we just pass the `--dry-run` option there and get the count from those functions only.","replyTo":null,"isNewFile":"1","line":"3898","lineLength":"0","path":"mercurial\/commands.py","diffId":"7877","author":"pulkit","id":"57179","dateCreated":"1526844970","dateModified":"1526844970"},{"type":"comment","comment":"@pulkit Can you please review it?","author":"khanchi97","id":"51519","dateCreated":"1523353338","dateModified":"1523353338"},{"type":"update","diffId":"7877","author":"khanchi97","id":"51174","dateCreated":"1523185235","dateModified":"1523185235"},{"type":"inline","comment":"`\"cannot use --dry-run without target phase\"`","replyTo":null,"isNewFile":"1","line":"3872","lineLength":"0","path":"mercurial\/commands.py","diffId":"7874","author":"av6","id":"51173","dateCreated":"1523167056","dateModified":"1523167056"},{"type":"update","diffId":"7874","author":"khanchi97","id":"51159","dateCreated":"1523101349","dateModified":"1523101349"},{"type":"update","diffId":"7873","author":"khanchi97","id":"51153","dateCreated":"1523100805","dateModified":"1523100805"}],"dateCreated":"1523100805","dateModified":"1579887184","status":"Needs Revision"},{"id":"3664","callsign":"HG","title":"graft: reuse the --edit value passed initially in `hg graft --continue` (BC)","author":"pulkit","summary":"This patch starts storing the value of --edit flag passed by the user initially\nwhen they runs `hg graft --edit`. We can now read the value from graftstate in\ncase of `--continue` and respect the value which user passed earlier.\n\nThe tests changes demonstrate the fix.","testPlan":"","lineCount":"28","dependsOn":["3663"],"reviewers":["baymax"],"ccs":["yuja","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117688","dateCreated":"1579887182","dateModified":"1579887182"},{"type":"reject","author":"baymax","id":"117687","dateCreated":"1579887182","dateModified":"1579887182"},{"type":"comment","comment":"Queued the first two, thanks.\n\n> This patch starts storing the value of --edit flag passed by the user initially\n> when they runs `hg graft --edit`. We can now read the value from graftstate in\n> case of `--continue` and respect the value which user passed earlier.\n\nI'm -0.5 on this since --edit is an option to change the interactive behavior,\nand I think we don't preserve such options across interrupted sessions.","author":"yuja","id":"58065","dateCreated":"1528200002","dateModified":"1528200002"},{"type":"update","diffId":"8909","author":"pulkit","id":"57568","dateCreated":"1527287139","dateModified":"1527287139"}],"dateCreated":"1527287139","dateModified":"1579887182","status":"Needs Revision"},{"id":"2945","callsign":"HG","title":"state: add a magicheader to each state file","author":"pulkit","summary":"This patch adds a magic header to each state file written using CBOR format so\nthat we can distinguish between old state files and new one even if old state\nfiles get successfully parsed by cbor.","testPlan":"","lineCount":"1","dependsOn":[],"reviewers":["baymax"],"ccs":["jeffpc","yuja","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117685","dateCreated":"1579887181","dateModified":"1579887181"},{"type":"reject","author":"baymax","id":"117684","dateCreated":"1579887181","dateModified":"1579887181"},{"type":"comment","comment":">>! In D2945#58586, @pulkit wrote:\n> There is a suggestion from @jeffpc to have a plain text header in statefiles like `HGStateFile` so that user can grep for them or look into files and know that they are state files. How does that sound?\n> (@jeffpc I am not sure I explained this correctly, it will be great if you can chime in.)\n\nI don't really care about the actual string value, I just think it is a good storage design practice to have every on-disk structure contain a magic value of some sort. (Beware, I have a storage background and therefore opinions about these things... ;) ) This makes it easier to do all sort of data recovery should the need arise. E.g.,\n\n - if you know that a random file (e.g., from lost+found) is a hg state file, you can ignore\/delete it and just reclone your repos\n - hg can detect some corruption better, and depending on the state file regenerate it or error out\n - hg developers can more easily sort out what's what when looking at buffers\/files\/etc.\n - as an added bonus, the magic can be used for format versioning\n\n\nFWIW, the three major things that I consider essential to good on-disk structures:\n\n # magic numbers - see above\n # checksums - possibly two checksums: one for the header and one for the payload\n # back-pointers - see below\n\nBack-pointers allow you to tie the file\/buffer into the bigger context - be it which state file it is, or which repository it belongs to. In this case a state file's back-pointer could be something like the repo-id + state-file-name stored in the state file's header. (I realize that there is no repo-id, but in general some approximation of it tends to be better than nothing.) This should make it painfully obvious what data one is dealing with and how to parse\/interpret it just by looking at the byte-stream without any other context.\n\n\nBy the way, I think that the magic should *not* be part of the CBOR payload but rather be at a fixed location in the file. The easier it is to find, the easier it is to detect issues (and to avoid trying to decode bad\/malicious input).","author":"jeffpc","id":"58725","dateCreated":"1529024379","dateModified":"1529024509"},{"type":"comment","comment":"There is a suggestion from @jeffpc to have a plain text header in statefiles like `HGStateFile` so that user can grep for them or look into files and know that they are state files. How does that sound?\n(@jeffpc I am not sure I explained this correctly, it will be great if you can chime in.)","author":"pulkit","id":"58587","dateCreated":"1529007034","dateModified":"1529007034"},{"type":"comment","comment":"> There are some old state files, which don't have a version header on top\n> of them like graftstate. I need suggestion on how to handle them.\n\nIn that case, we would have to either do some heuristic (like histedit), or maintain\nold\/new state files (like mergestate.) Perhaps graft can do the latter?","author":"yuja","id":"47899","dateCreated":"1522244380","dateModified":"1522244380"},{"type":"comment","comment":">>! In D2945#47831, @yuja wrote:\n> I think the magic has to vary depending on the current state file format.\n> The state file must be backward\/forward compatible with the older\/newer formats.\n> \n> If the current magic is `2\\n` (and is parsed as `int(f.readline())`) for example, the\n> CBOR preamble would have to be `3\\n`. Otherwise, old hg client cant determine\n> whether the state file is corrupted or written by newer client.\n\nThere are some old state files, which don't have a version header on top of them like graftstate. I need suggestion on how to handle them.\n","author":"pulkit","id":"47892","dateCreated":"1522235138","dateModified":"1522235138"},{"type":"comment","comment":"I think the magic has to vary depending on the current state file format.\nThe state file must be backward\/forward compatible with the older\/newer formats.\n\nIf the current magic is `2\\n` (and is parsed as `int(f.readline())`) for example, the\nCBOR preamble would have to be `3\\n`. Otherwise, old hg client cant determine\nwhether the state file is corrupted or written by newer client.\n\nFWIW, last time I reviewed `simplekeyvaluefile`, I insisted that a parser should\ntake a file stream instead of a filename, so the caller can handle compatibility thingy.\n\n```\nwith open(\"statefile\", \"rb\") as fp:\n try:\n version = int(fp.readline())\n except ValueError:\n raise some nicer exception\n if version == 2:\n return readold(fp)\n elif version == 3:\n return readcbor(fp)\n```","author":"yuja","id":"47832","dateCreated":"1522155487","dateModified":"1522155487"},{"type":"update","diffId":"7299","author":"pulkit","id":"47624","dateCreated":"1522084159","dateModified":"1522084159"}],"dateCreated":"1522084159","dateModified":"1579887181","status":"Needs Revision"},{"id":"3650","callsign":"HG","title":"serve: add an option to open in the default browser","author":"nspanti-logilab","summary":"It is inspired by a similar functionality in pydoc. `-g`\/`--graphical` may not be adequate, the only other idea that I have is `-w`\/`--window`.","testPlan":"","lineCount":"42","dependsOn":[],"reviewers":["baymax"],"ccs":["yuja","pulkit","av6","durin42","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117682","dateCreated":"1579887179","dateModified":"1579887179"},{"type":"reject","author":"baymax","id":"117681","dateCreated":"1579887179","dateModified":"1579887179"},{"type":"comment","comment":"(Resend because I forgot to remove the \"someone wrote:\" line again, sorry.)\n\n> For laziness, this patch could be also useful. It is also better for text shell beginners, because they may not know that they can combine commands like that (even if it is basic).\n\nFor laziness, we can add it to `[alias]`. I'm not a fan of adding lots of\none-off options since that's the source of man page bloat.\n\nHow about document the xdg-open example in `hg help serve -v`?","author":"yuja","id":"58867","dateCreated":"1529155285","dateModified":"1529155285"},{"type":"comment","comment":"For laziness, this patch could be also useful. It is also better for text shell beginners, because they may not know that they can combine commands like that (even if it is basic). Moreover, you can still use `hg serve` in foreground or use it in background and give the result of `--print-url` to a non web browser application (but I imagine that there is a way to duplicate stdout to multiple programs). These are the advantages of this patch that I see over `--print-url` of D3649. It is better for convenience and require less knowledge for the user, but it is not a need. D3649 was precisely suggested to me because it can fulfill the functionality of the current patch and is more versatile.","author":"nspanti-logilab","id":"58735","dateCreated":"1529052032","dateModified":"1529052032"},{"type":"comment","comment":"Do we need this patch any more since D3649 has landed and we can do `xdg-open \"$(hg serve --print-url)\"`?","author":"pulkit","id":"58567","dateCreated":"1529005653","dateModified":"1529005653"},{"type":"comment","comment":"D3649 mentions `xdg-open \"$(hg serve --print-url)\"`, which shows that --print-url can nearly replace --graphical and is more versatile.","author":"av6","id":"57842","dateCreated":"1527944680","dateModified":"1527944680"},{"type":"comment","comment":"I don't love the flag name, and am -0 on the feature in general. All terminal emulators I've used in the last 10 years have URL detection logic and make clicking the link trivial...","author":"durin42","id":"57770","dateCreated":"1527794132","dateModified":"1527794132"},{"type":"update","diffId":"8881","author":"nspanti-logilab","id":"57359","dateCreated":"1527168904","dateModified":"1527168904"}],"dateCreated":"1527168904","dateModified":"1579887180","status":"Needs Revision"},{"id":"3672","callsign":"HG","title":"retractboundary: add dryrun parameter","author":"khanchi97","summary":"Added the logic to find those csets whose phase will be changed\nwithout --dry-run and return those csets.","testPlan":"","lineCount":"66","dependsOn":[],"reviewers":["baymax"],"ccs":["yuja","pulkit","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117679","dateCreated":"1579887178","dateModified":"1579887178"},{"type":"reject","author":"baymax","id":"117678","dateCreated":"1579887178","dateModified":"1579887178"},{"type":"inline","comment":"I think affected can be used here. Maybe @yuja might know better.\n\n@yuja we want to return a set of revs whose phase is changed by this function. Does affected looks like the correct set to you?","replyTo":"57830","isNewFile":"1","line":"417","lineLength":"0","path":"mercurial\/phases.py","diffId":"8948","author":"pulkit","id":"61254","dateCreated":"1531344290","dateModified":"1531344290"},{"type":"update","diffId":"8960","author":"khanchi97","id":"57892","dateCreated":"1528034158","dateModified":"1528034158"},{"type":"update","diffId":"8959","author":"khanchi97","id":"57891","dateCreated":"1528033881","dateModified":"1528033881"},{"type":"inline","comment":"okay, will do this for 'advanceboundry' too","replyTo":"57825","isNewFile":"1","line":"511","lineLength":"0","path":"mercurial\/phases.py","diffId":"8948","author":"khanchi97","id":"57833","dateCreated":"1527857439","dateModified":"1527857439"},{"type":"inline","comment":"yeah, I got it.","replyTo":"57824","isNewFile":"1","line":"430","lineLength":"0","path":"mercurial\/phases.py","diffId":"8948","author":"khanchi97","id":"57832","dateCreated":"1527857439","dateModified":"1527857439"},{"type":"inline","comment":"okay","replyTo":"57823","isNewFile":"1","line":"395","lineLength":"0","path":"mercurial\/phases.py","diffId":"8948","author":"khanchi97","id":"57831","dateCreated":"1527857439","dateModified":"1527857439"},{"type":"inline","comment":"Because I think this affected set is calculated after performing actions, when phases are changed. And calculating affected using new phaseroots. Am I missing something here?","replyTo":"57822","isNewFile":"1","line":"417","lineLength":"0","path":"mercurial\/phases.py","diffId":"8948","author":"khanchi97","id":"57830","dateCreated":"1527857439","dateModified":"1527857439"},{"type":"inline","comment":"This should better be:\n\n`If dryrun is True, no actions will be performed\n\nreturns a set of revs whose phase is changed or should be changed`","replyTo":null,"isNewFile":"1","line":"511","lineLength":"0","path":"mercurial\/phases.py","diffId":"8948","author":"pulkit","id":"57825","dateCreated":"1527845546","dateModified":"1527845546"},{"type":"inline","comment":"(Not sure which line I should put this comment on)\n\nJust like D3671, here also, the function should return the correct set of changes whose phase have been changed irrespective of the dryrun value passed.","replyTo":null,"isNewFile":"1","line":"430","lineLength":"0","path":"mercurial\/phases.py","diffId":"8948","author":"pulkit","id":"57824","dateCreated":"1527845546","dateModified":"1527845546"},{"type":"inline","comment":"Add documentation about dry-run and the return value.","replyTo":null,"isNewFile":"1","line":"395","lineLength":"0","path":"mercurial\/phases.py","diffId":"8948","author":"pulkit","id":"57823","dateCreated":"1527845546","dateModified":"1527845546"},{"type":"inline","comment":"Why are we not using this affected set here to find the changesets whose phase is changed?","replyTo":null,"isNewFile":"1","line":"417","lineLength":"0","path":"mercurial\/phases.py","diffId":"8948","author":"pulkit","id":"57822","dateCreated":"1527845546","dateModified":"1527845546"},{"type":"update","diffId":"8948","author":"khanchi97","id":"57812","dateCreated":"1527836390","dateModified":"1527836390"},{"type":"update","diffId":"8929","author":"khanchi97","id":"57663","dateCreated":"1527675912","dateModified":"1527675912"}],"dateCreated":"1527675912","dateModified":"1579887179","status":"Needs Revision"},{"id":"3830","callsign":"HG","title":"rebase: suppress transaction warns during dry-run","author":"khanchi97","summary":"Suppressed warnings thrown while aborting a transaction during\ndryrun because these warnings does not sound safe to user.","testPlan":"","lineCount":"23","dependsOn":[],"reviewers":["baymax","martinvonz"],"ccs":["mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117675","dateCreated":"1579887177","dateModified":"1579887177"},{"type":"reject","author":"baymax","id":"117674","dateCreated":"1579887177","dateModified":"1579887177"},{"type":"update","diffId":"9593","author":"khanchi97","id":"61465","dateCreated":"1531549446","dateModified":"1531549446"},{"type":"update","diffId":"9501","author":"khanchi97","id":"60911","dateCreated":"1531233875","dateModified":"1531233875"},{"type":"update","diffId":"9384","author":"khanchi97","id":"60399","dateCreated":"1530438740","dateModified":"1530438740"},{"type":"update","diffId":"9359","author":"khanchi97","id":"60261","dateCreated":"1530295767","dateModified":"1530295767"},{"type":"update","diffId":"9347","author":"khanchi97","id":"60219","dateCreated":"1530216657","dateModified":"1530216657"},{"type":"update","diffId":"9269","author":"khanchi97","id":"59837","dateCreated":"1529835539","dateModified":"1529835539"},{"type":"update","diffId":"9267","author":"khanchi97","id":"59827","dateCreated":"1529832650","dateModified":"1529832650"}],"dateCreated":"1529832650","dateModified":"1579887177","status":"Needs Revision"},{"id":"3946","callsign":"HG","title":"obsolete: resolved ValueError for var containing 2 ':' chars(issue-5783)","author":"abhyudaypratap","summary":"feature Note accepts ':' chars\nSo metadata of obsmarker consists of more then 1 ':' char,\nThe content of the variable 'data' in this function is:\n'date:1518013344.878793 -3600\\x00ef1:0\\x00note:6c95ca::a1e17f\\x00p1:ed7673f73387b36521da58a87f08e02e4a795ded\\x00user:Denis Laxalde <xxx@yyy.zz>'\n\nresulting in giving a error ValueError (too many values to unpack) because we are trying to store multiple values into two variables key and value\n\nResolving this error by splitting the variable 'l' from the first occurence of ':'\nkey, value = l.split(\"\", 1)","testPlan":"","lineCount":"2","dependsOn":[],"reviewers":["baymax"],"ccs":["yuja","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117672","dateCreated":"1579887176","dateModified":"1579887176"},{"type":"reject","author":"baymax","id":"117671","dateCreated":"1579887176","dateModified":"1579887176"},{"type":"comment","comment":"Looks good. Can you add a test?\n\nhttps:\/\/www.mercurial-scm.org\/wiki\/ContributingChanges#Coding_style_and_testing\n\nThe version 0 format can be enforced by `--config format.obsstore-version=0`.","author":"yuja","id":"61491","dateCreated":"1531661257","dateModified":"1531661257"},{"type":"update","diffId":"9596","author":"abhyudaypratap","id":"61478","dateCreated":"1531593829","dateModified":"1531593829"}],"dateCreated":"1531593829","dateModified":"1579887176","status":"Needs Revision"},{"id":"3986","callsign":"HG","title":"split: abort if there's an unfinished operation","author":"martinvonz","summary":"","testPlan":"","lineCount":"10","dependsOn":[],"reviewers":["baymax"],"ccs":["quark","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117669","dateCreated":"1579887175","dateModified":"1579887175"},{"type":"reject","author":"baymax","id":"117668","dateCreated":"1579887175","dateModified":"1579887175"},{"type":"comment","comment":"I think a most flexible solution is to not do the check if there is nothing to rebase.","author":"quark","id":"62080","dateCreated":"1533137720","dateModified":"1533137720"},{"type":"comment","comment":"Oh, I should have said that I agree with not queuing this patch now. We can discuss what we want to do and do it on the default branch later.","author":"martinvonz","id":"61992","dateCreated":"1533018979","dateModified":"1533018979"},{"type":"comment","comment":">>! In D3986#61989, @quark wrote:\n> FB has users reporting they need to split commits in the middle of a histedit. So this might be too restrictive.\n\nTwo thoughts:\n\n1. We had talked at Google about having the \"edit\" action create split markers if the user created multiple commits. Do you think that would address the FB users' use case?\n\n2. It seems very dangerous to not have this check at least when not using obsmarkers and there are descendants of the current commit (split then rebases the descendants), so I'd like to keep the check in at least that case.\n","author":"martinvonz","id":"61991","dateCreated":"1533014407","dateModified":"1533014407"},{"type":"comment","comment":"FB has users reporting they need to split commits in the middle of a histedit. So this might be too restrictive.","author":"quark","id":"61990","dateCreated":"1533014171","dateModified":"1533014171"},{"type":"update","diffId":"9671","author":"martinvonz","id":"61978","dateCreated":"1532987112","dateModified":"1532987112"}],"dateCreated":"1532987112","dateModified":"1579887175","status":"Needs Revision"},{"id":"4053","callsign":"HG","title":"[RFC]hgweb: garbage collect on every request in hgweb_mod too","author":"pulkit","summary":"We recently updated to mercurial 4.6.2 on our servers and also increased number\nof requests to be made on server at one time. This made hgweb instance takes up\na lot of memory, sometime upto 50GB of memory when requests are made parallely.\n\nThis patch is motivated from\nhttps:\/\/www.mercurial-scm.org\/repo\/hg-committed\/rev\/ff2370a70fe8 which adds\ngc.collect() call for the server which serves multiple repositories.\n\nI tried profiling this fix, sometimes this shows less memory usage, sometimes\nmore, so I am not sure whether this is right and hence RFC tag.","testPlan":"","lineCount":"16","dependsOn":[],"reviewers":["baymax"],"ccs":["av6","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117666","dateCreated":"1579887174","dateModified":"1579887174"},{"type":"reject","author":"baymax","id":"117665","dateCreated":"1579887174","dateModified":"1579887174"},{"type":"comment","comment":">>! In D4053#62855, @av6 wrote:\n> Are you sure you're not just using hgwebdir_mod? hgweb_mod is for cases when you don't use --web-conf flag, at least that seems to be the logic that `hgweb.createapp()` uses to pick one of the two modules.\n\nI checked and we are using hgwebdir_mod. When I was testing locally I was not using --web-conf flag, so maybe that's why I ran into `hgweb_mod`. The problem still exists though and we have limited the number of requests at once. Thanks!","author":"pulkit","id":"65973","dateCreated":"1534331436","dateModified":"1534331436"},{"type":"comment","comment":"Are you sure you're not just using hgwebdir_mod? hgweb_mod is for cases when you don't use --web-conf flag, at least that seems to be the logic that `hgweb.createapp()` uses to pick one of the two modules.","author":"av6","id":"62856","dateCreated":"1533231595","dateModified":"1533231595"},{"type":"update","diffId":"9792","author":"pulkit","id":"62851","dateCreated":"1533225478","dateModified":"1533225478"},{"type":"update","diffId":"9787","author":"pulkit","id":"62829","dateCreated":"1533219726","dateModified":"1533219726"}],"dateCreated":"1533219726","dateModified":"1579887174","status":"Needs Revision"},{"id":"4301","callsign":"HG","title":"tests: add a directory 'knownfailures' to check in known failures","author":"pulkit","summary":"There are some things which everyone of us stumble upon and found out that this\ndoes not work. Sometimes, we hg developers know that these things does not works\nbecause of experience. But this does not scale well when we have a new developer\nor maybe a user who wants to see what does not work and is interested in fixing\nthat.\n\nChecking in the tests about the things which don't work will help others to\nreproduce these and also helps in fixing because of functionalities\n.\/run-tests.py provides.\n\nIIRC we had this thought in one of the previous sprints also to checkin some of\nthe known failures.\n\nI am starting with checking in a basic test failure. But I plan to check in\nmore narrow related failures which we have found.\n\nUnable to find easily what exactly broken with merges and narrow made me to\nimplement this idea so that we won't have similar problem in future.","testPlan":"","lineCount":"4","dependsOn":[],"reviewers":["durin42","baymax"],"ccs":["mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117660","dateCreated":"1579887171","dateModified":"1579887171"},{"type":"reject","author":"baymax","id":"117659","dateCreated":"1579887171","dateModified":"1579887171"},{"type":"comment","comment":"I also think that the 'knowfailures' can serve as a good place for new contributors.\nI don't want to check-in all the failures and leave them unfixed. It's like I don't know which one I will be able to fix and I have a reproduction which can help others.","author":"pulkit","id":"66188","dateCreated":"1534432054","dateModified":"1534432054"},{"type":"update","diffId":"10391","author":"pulkit","id":"66182","dateCreated":"1534431586","dateModified":"1534431586"}],"dateCreated":"1534431586","dateModified":"1579887172","status":"Needs Revision"},{"id":"4409","callsign":"HG","title":"rebase: skip *all* obsolete revisions, just warn about divergence","author":"martinvonz","summary":"We already skip obsolete revisions in some case: if there is no\nsuccessor, or when the successor is in the rebase set or in the\ndestination, I think. However, we instead error out if the successor\nis elsewhere (e.g. a child or a sibling of the destination), because\nit would cause divergence. The previous commit fixed one specific case\nof this.\n\nConsider this history (based on a test case updated by this patch):\n\n o D\n |\n | o B'\n |\/\n | o C\n | |\n | x B\n |\/\n o A\n\nIf the user now runs `hg rebase -s B -d D` we would error out and tell\nthem that it would cause divergence from B. This patch makes it so we\ninstead ignore B and C (and tell the user that we're doing that\nbecause it would cause divergence). I think this simpler model will be\neasier for users to understand (I had also thought that all obsolete\ncommits and their descendants were skipped until we got reports from\nusers that that wasn't the case).\n\nNote that we still skip just the obsolete (not its descendants) if\nit's a prune or if the successor is in the destination.\n\nThis should also let us simplify the source quite a bit. I'll do that\nin later commits after I've heard people's thoughts on this one.","testPlan":"","lineCount":"40","dependsOn":[],"reviewers":["baymax"],"ccs":["lothiraldan","yuja","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117657","dateCreated":"1579887170","dateModified":"1579887170"},{"type":"reject","author":"baymax","id":"117656","dateCreated":"1579887170","dateModified":"1579887170"},{"type":"comment","comment":"Changing the behavior of `--src` to ignore obsolete and orphan unrelated to the destination seems like a good idea.\n\nHowever, this change seems to also affect `--rev`. The `--rev` allow for a precise selection of what the user wants to see rebased and it feels like we should stick to the user wishes here. Dropping explicitly selected revisions feels wrong and will make some use cases harder to perform.","author":"lothiraldan","id":"67654","dateCreated":"1535551219","dateModified":"1535551219"},{"type":"comment","comment":"> @@ -1289,18 +1286,16 @@\n> o 0:b173517d0057 a\n> \n> $ hg rebase -d 0 -r 2\n> - rebasing 2:a82ac2b38757 \"c\" (c)\n> + note: not rebasing 2:a82ac2b38757 \"c\" (c) and its descendants as this would cause divergence\n\nLooks like the fix for issue5782 regressed.\n\nhttps:\/\/bz.mercurial-scm.org\/show_bug.cgi?id=5782","author":"yuja","id":"67642","dateCreated":"1535547342","dateModified":"1535547342"},{"type":"update","diffId":"10616","author":"martinvonz","id":"67528","dateCreated":"1535441604","dateModified":"1535441604"}],"dateCreated":"1535441604","dateModified":"1579887170","status":"Needs Revision"},{"id":"4479","callsign":"HG","title":"[RFC] obsolete: add mechanism to filter obsstore","author":"lothiraldan","summary":"This patch is not ready to land and only sent for discussion.","testPlan":"","lineCount":"24","dependsOn":[],"reviewers":["baymax"],"ccs":["pulkit","martinvonz","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117654","dateCreated":"1579887168","dateModified":"1579887168"},{"type":"reject","author":"baymax","id":"117653","dateCreated":"1579887168","dateModified":"1579887168"},{"type":"comment","comment":"I just had a quick look. obsmarker repr hash, are we kind of inventing a way to index obsmarkers? I am pretty sure you people have thought about that, can you explain why you went with obsmarker repr hash instead of including a real index?\n\nAlso, feel free to point me to old discussions if this was discussed earlier.","author":"pulkit","id":"68685","dateCreated":"1536183949","dateModified":"1536183949"},{"type":"comment","comment":"I'll reply to my own question: The context is in D2679.","author":"martinvonz","id":"68491","dateCreated":"1536103749","dateModified":"1536103749"},{"type":"comment","comment":"Why? (Sorry if I'm asking to early and you were just about to send an update.)","author":"martinvonz","id":"68488","dateCreated":"1536103366","dateModified":"1536103366"},{"type":"update","diffId":"10777","author":"lothiraldan","id":"68482","dateCreated":"1536103193","dateModified":"1536103193"}],"dateCreated":"1536103193","dateModified":"1579887169","status":"Needs Revision"},{"id":"4716","callsign":"HG","title":"lfs: don't add extension to hgrc after clone or share (BC)","author":"indygreg","summary":"Now that repository loading in core supports automatically loading\nthe lfs extension when the \"lfs\" requirement is present, we no\nlonger need to update the .hg\/hgrc of newly-created repos to load\nthe lfs extension!\n\nI'm marking this as BC because it is a change in behavior. But users\nshould not notice unless they create an LFS repo with new Mercurial\nand then attempt to use it with an old versions that doesn't support\nautomatic extension loading.","testPlan":"","lineCount":"36","dependsOn":[],"reviewers":["baymax"],"ccs":["mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117651","dateCreated":"1579887167","dateModified":"1579887167"},{"type":"reject","author":"baymax","id":"117650","dateCreated":"1579887167","dateModified":"1579887167"},{"type":"update","diffId":"11324","author":"indygreg","id":"71559","dateCreated":"1537805608","dateModified":"1537805608"}],"dateCreated":"1537805608","dateModified":"1579887167","status":"Needs Revision"},{"id":"2679","callsign":"HG","title":"[PoC] obsolete: config option to enable local only obsolescence mode","author":"indygreg","summary":"Our path to enable obsolescence\/evolve in core is to enable\ncreation of markers locally (no exchange) with user-facing behavior\nthat mimics existing behavior as closely as possible. Think of it\nas evolve light.\n\nWe introduce a config option to control this behavior.","testPlan":"","lineCount":"14","dependsOn":[],"reviewers":["baymax"],"ccs":["martinvonz","markand","durin42","lothiraldan","pulkit","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117648","dateCreated":"1579887165","dateModified":"1579887165"},{"type":"reject","author":"baymax","id":"117647","dateCreated":"1579887165","dateModified":"1579887165"},{"type":"comment","comment":">>! In D2679#73347, @martinvonz wrote:\n> Here's a case I just ran into where I would have liked to de-obsolete a commit:\n> \n> 1. Someone queues a patch and pushes to central repo. Repo looks like this:\n\nYou are using the words \"Someone queues a patch\", is your example taken from the current Mercurial project workflow? If so, keep in mind that this workflow is a bit unique. It is not what we refer as \"distributed evolution\" and diverges from it in various ways. In particular, we can highlight the following difference:\n\n\n - Contributions are exchanged through email or Phabricator. Both ways fail to transfers the associated obsmarkers (and therefore break the evolution chains). \n Instead people using distributed evolution exchanges changesets through mercurial repositories, fully taking advantage of the obsmarkers data. This makes it possible for them to collaborate on the same feature branch and other evolution benefits (eg: evolution data in code review tools).\n - The publication workflow is odds as hundreds of unrelated draft changeset can stack above each other before being published. This is not really the use-case that draft phase and evolution targets.\n> \n> ```\n> o B\n> |\n> o A\n> ```\n> \n> 2. I fix a typo and and amend, but I forget to push. \n> 3. I build my own commit on top. My repo:\n> \n> ```\n> o X\n> |\n> o B'\n> |\n> o A\n> ```\nSmall side question: Why are you building X on top of (draft) B', are they related?\n> \n> 4. Someone pushes new patches to central repo. Central repo:\n> \n> ```\n> o C\n> |\n> o B\n> |\n> o A\n> ```\nAdditional side question: Why is C on top of (draft) B. Are they related?\n> \n> 5. I pull from central repo. My repo:\n> \n> ```\n> o C\n> |\n> x B\n> |\n> | o X\n> | |\n> | o B'\n> |\/\n> o A\n> ```\n> \n> 6. I move my change onto the new upstream and prune my local B' that's now unwanted:\n> \n> ```\n> o X'\n> |\n> o C\n> |\n> x B\n> |\n> | x B'\n> |\/\n> o A\n> ```\n> \n> If upstream history was really just a single commit (`C` above), then the obvious thing to do is to just evolve that commit and push it. However, sometimes there is a long chain on top, and in my case there was a separate commit upstream that fixed the typo I fixed when I amended `B` and it would be a little confusing to explain why someone's fix was \"lost\". \n\nI can see two distinct arguments in that description:\n # Someone else made a similar fix in an independent changeset, and you want to give them the priority.\n # There are many drafts stacked above it and you don't want to rewrite B.\n\n\nRegarding the first argument, the case is easily handled by \"rewinding\" your amend's change and restoring the diff provided by 'B'. The `hg rewind` command deal with this case well: `hg rewind --to B`. The use of `hg prune` in your example is wrong. By using prune, you signal that the full line of change in B' (B' and it predecessors B) is something that is unwanted. So you are not just dropping the change introduced in your amend, but the other associated change.\n\nRegarding the second argument, the one I interpret as it would create too many orphans.\nIt seems to be the consequence of the current Mercurial Project workflow where many unrelated drafts get stacked.\nThe point of the draft phase is to signal that a changeset is safe to be rewritten. In other words that the consequences of such rewriting are acceptable. If you get to the point where rewriting draft no longer feel safe you seem to have a workflow issue.\n\nFor the sake of the current argument, let's assume that the workflow would be fixed in a direction where B would be public. After your pull. In that case, B' would be \"phase-divergent\". Solving that phase-divergence will create a \u0394B changeset with just the fix (you amend change). Rebasing that \u0394B on top of the other fix will make it disappears, giving priority as you intended.\n\n> So I'd prefer to mark B as no longer obsolete. I know I can do that with `hg strip B'`, but that also strips `X`, which is probably not a big loss, but it's a weird side-effect.\n\nYou cannot really strip the obsmarkers between B and B' without stripping B' itself. If B' end up being visible again it's Evolve that would be lost introducing confusion too.\n\n> Perhaps all I'm asking for is a way of dropping the obsmarker between `B` and `B'`. I don't know what the best UI for that would be, though. For now, I guess I'll use `hg strip`.\n\nStripping obsmarkers (and changesets) gets tricky quickly as their might continue to exist elsewhere. [issue5267](https:\/\/bz.mercurial-scm.org\/show_bug.cgi?id=5267) is a good example. There is already a couple of ways to do it (hg strip or hg debugobsolete) but it is currently confined into advanced commands. Before smoothing special case that could benefit stripping (or equivalent feature), it is important to deal with the UI for the main use-case. The use-case that solves both local and distributed evolution with the same command set. We want this commands set to comes first as we know it will be necessary. We can add more advanced commands and concept to deal with stripping afterward.\n\n\nLet me clarify that last part: imagine two commands (or command set, or concepts):\n\n # Command-A handles cases for both local and distributed evolution,\n # Command-B only handles local evolution, but deal with a corner case a bit later.\n\n\nIf we introduce Command-A early, we can foster a good user experience that will be the same for local and distributed case. This makes the \"step\" to distributed usage simple and painless. The overall user experience and other commands will make sure they work smoothly with Command-A. Later, we can introduce Command-B that will deal with specialized cases were Command-A is lacking. Since Command-A is already covering the main use-cases well, Command-B can focus on dealing with the specialized cases only. Each command has clear responsibilities.\n\nOn the other hand, introducing Command-B first will create a user experience that does not cover all of the main use-cases. The later arrival of Command-A will introduce an overlap in responsibilities confusing to users. In addition, it will create a problematic step to move from the local experience to the distributed one. Users will have to \"forget\" their previous usage to be able to get the better of Mercurial, this will create more confusion.","author":"lothiraldan","id":"74342","dateCreated":"1539204897","dateModified":"1539204897"},{"type":"comment","comment":"Here's a case I just ran into where I would have liked to de-obsolete a commit:\n\n1. Someone queues a patch and pushes to central repo. Repo looks like this:\n\n```\no B\n|\no A\n```\n\n2. I fix a typo and and amend, but I forget to push. \n3. I build my own commit on top. My repo:\n\n```\no X\n|\no B'\n|\no A\n```\n\n4. Someone pushes new patches to central repo. Central repo:\n\n```\no C\n|\no B\n|\no A\n```\n\n5. I pull from central repo. My repo:\n\n```\no C\n|\nx B\n|\n| o X\n| |\n| o B'\n|\/\no A\n```\n\n6. I move my change onto the new upstream and prune my local B' that's now unwanted:\n\n```\no X'\n|\no C\n|\nx B\n|\n| x B'\n|\/\no A\n```\n\nIf upstream history was really just a single commit (`C` above), then the obvious thing to do is to just evolve that commit and push it. However, sometimes there is a long chain on top, and in my case there was a separate commit upstream that fixed the typo I fixed when I amended `B` and it would be a little confusing to explain why someone's fix was \"lost\". So I'd prefer to mark B as no longer obsolete. I know I can do that with `hg strip B'`, but that also strips `X`, which is probably not a big loss, but it's a weird side-effect. Perhaps all I'm asking for is a way of dropping the obsmarker between `B` and `B'`. I don't know what the best UI for that would be, though. For now, I guess I'll use `hg strip`.","author":"martinvonz","id":"73348","dateCreated":"1538584552","dateModified":"1538584552"},{"type":"inline","comment":"https:\/\/www.mercurial-scm.org\/wiki\/UIGuideline#naming_config_options","replyTo":null,"isNewFile":"1","line":"1041","lineLength":"0","path":"mercurial\/configitems.py","diffId":"6637","author":"markand","id":"73020","dateCreated":"1538468057","dateModified":"1538468057"},{"type":"comment","comment":">>! In D2679#70935, @durin42 wrote:\n>>>! In D2679#70934, @lothiraldan wrote:\n>>>>! In D2679#69388, @durin42 wrote:\n>>> I'm slowly becoming convinced that the long-unquestioned axiom that \"all markers are distributed globally\" isn't correct, and this is part of why: it's potentially of great value to be able to restore a change by re-pulling it, even though the obsmarkers would normally cause it to be deleted.\n>> Avoiding silent reappearance of the locally obsolete changeset that we see on a remote repository is a core feature of obsolescence. Actually, it is the one issue that prompted the creation of changeset evolution in the first place. \n> \n> There's a difference (in my view) between something accidentally coming back and intentionally coming back. The current state of affairs prevents both. I feel like we can do better.\n\nI feel like detecting if an obsolete changeset is re-added accidentally or intentionally is a near impossible problem. We have submitted code recently to detect when an obsolete changeset is re-added, but again we don't know if it is accidentally or intentionally. The safe path here is to inform the user about suspicious situations and give them the tool to explicitly restore changesets they want to be restored. That why we have been working on an explicit `hg rewind` command in evolve.\n\n> \n>> We and the other people using distributed evolution rely on this behavior on a daily basis. The includes people who picked up the evolve extension on their own and came up with their own workflow without ever speaking to us. We can see some user interfaces adjustment in the future, but the set of synchronized markers and the associated behavior is something we are happy about. It has been well tested in diverse teams and situation for multiple years now.\n> \n> I've brought this up repeatedly and been dismissed with this exact argument every time. I weary of it, because it's not a new argument, it's just blind devotion to the initial design without any attempt at reflection if we can do better.\n\n\nSince I joined Octobus, I've witnessed the exploration of all the remaining uncharted territories and solving of most of the resulting associated challenges. In particular, some important aspects of distributed evolution: instabilities resolutions and efficient obsmarkers exchanges have been solved and have working implementations used on a daily basis. We did alter the initial design when deemed so by new information from exploration or feedback of evolve users.\nDuring these developments, we did not find reasons to challenge the obsolescence core concepts. They, in fact, proved a useful help to build solutions to the distributed evolution challenges. To name a few of these progress and design changes: vocabulary renaming, the missing commands for history exploration and reviving, the new discovery protocol and more recently how to track fold in obsmarkers.\n\nIn a similar way, the numbers and types of distributed evolution users have grown and we had more and more opportunity to exchange with them. We base our plans on more than \"some people using it without complains\". They are a diverse and large corpus of people we have been talking to and studied their workflows. Here again, core concepts, in particular, the global state and instabilities are things that, practically helps teams to use distributed evolution workflows and newcomers to get a good grasp of it. Important behavior designed and tested in the past 5 years, like the exchange behavior, have been battle tested and real people rely on them in their day to day workflow.\n\nSo, it might seem like the same argument, but it is actually a stronger one. The data to back it kept growing in the past couple of years.\n\nIf you need more details, check our recent blog post about evolution: https:\/\/octobus.net\/blog\/2018-09-03-evolve-status-2018-08.html\n\n> I don't dispute that evolution as currently implemented is a good thing, but I feel like there's room for significant improvement while simultaneously simplifying the exchange algorithms. Care to try and convince me why I'm wrong, without anecdotal \"many people use this and haven't complained\" arguments?\n\n\nSure, the proposal in this PoC (\"unobsolete\" all re-added changesets) break basic distributed evolution workflow very quickly. Here are small examples among many. They display simple draft changesets roundtrips:\n\n- Example A:\n\n - I am working on a repository with a changeset A that is present also on my default server\n - I amend A into A'\n - I pull from my default server, the server doesn't know yet that A has been rewritten into A'. A is sent by the server.\n - A is hidden before the pull. Getting A to be visible again would be confusing for me as I would now have both A and A' \"alive\" at the same time.\n \n- Example B:\n\n - I am working on a repository with a changeset A that is present also on my default server\n - I amend A into A'\n - One of my coworkers push a changeset B on top of A to the server\n - I pull from my default server\n - I receive both B and A, and I have all the needed information to stabilize B and continue my work. I don't want A to become \"unobsolete\" on pull.\n\nWe can provide other examples if needed.\n\nCould you give some details about the improvements that you suggest and that what kind of core changes they would require and their effects on distributed evolution?\n","author":"lothiraldan","id":"72403","dateCreated":"1538147960","dateModified":"1538147960"},{"type":"comment","comment":">>! In D2679#70934, @lothiraldan wrote:\n>>>! In D2679#69388, @durin42 wrote:\n>> I'm slowly becoming convinced that the long-unquestioned axiom that \"all markers are distributed globally\" isn't correct, and this is part of why: it's potentially of great value to be able to restore a change by re-pulling it, even though the obsmarkers would normally cause it to be deleted.\n> Avoiding silent reappearance of the locally obsolete changeset that we see on a remote repository is a core feature of obsolescence. Actually, it is the one issue that prompted the creation of changeset evolution in the first place. \n\nThere's a difference (in my view) between something accidentally coming back and intentionally coming back. The current state of affairs prevents both. I feel like we can do better.\n\n> We and the other people using distributed evolution rely on this behavior on a daily basis. The includes people who picked up the evolve extension on their own and came up with their own workflow without ever speaking to us. We can see some user interfaces adjustment in the future, but the set of synchronized markers and the associated behavior is something we are happy about. It has been well tested in diverse teams and situation for multiple years now.\n\nI've brought this up repeatedly and been dismissed with this exact argument every time. I weary of it, because it's not a new argument, it's just blind devotion to the initial design without any attempt at reflection if we can do better. I don't dispute that evolution as currently implemented is a good thing, but I feel like there's room for significant improvement while simultaneously simplifying the exchange algorithms. Care to try and convince me why I'm wrong, without anecdotal \"many people use this and haven't complained\" arguments?\n\n>> It's _super confusing_ when I `hg import` a patch and it seems to work but also immediately disappears, so I've got more sympathy for this PoC series than I do the theoretical purity of markers having any kind of globalness. Does that make sense?\n> This seems like an unrelated user interface issues. We usually warn the user when their working copy becomes obsolete, pointing out to the newest version\/evolution. We have to extend this messages logic to `hg import` to clarify the situation.\n\nI disagree, perhaps unsurprisingly.","author":"durin42","id":"70935","dateCreated":"1537377795","dateModified":"1537377795"},{"type":"comment","comment":">>! In D2679#69388, @durin42 wrote:\n>>>! In D2679#68489, @lothiraldan wrote:\n>> To take a step back, I'm wondering what's the end goal? I remember there was a discussion about having rebase enabled by default, is it related?\n> \n> Getting rebase (and maybe histedit?) enabled by default is my recollection of the rough goal.\n> \n>> \n>> The behavior target by this series (\"unobsolete\" re-pulled changeset) conflicts with the final behavior we want for Changeset Evolution. Intermediate steps are a good way to make progress. I feel like it is important to write down a clear plan when it comes to adding behavior that does not match our final goals. How are we planning to transition from the local-only step to full (ie, distributed) Evolution?\n> \n> I'm slowly becoming convinced that the long-unquestioned axiom that \"all markers are distributed globally\" isn't correct, and this is part of why: it's potentially of great value to be able to restore a change by re-pulling it, even though the obsmarkers would normally cause it to be deleted.\nAvoiding silent reappearance of the locally obsolete changeset that we see on a remote repository is a core feature of obsolescence. Actually, it is the one issue that prompted the creation of changeset evolution in the first place. We and the other people using distributed evolution rely on this behavior on a daily basis. The includes people who picked up the evolve extension on their own and came up with their own workflow without ever speaking to us. We can see some user interfaces adjustment in the future, but the set of synchronized markers and the associated behavior is something we are happy about. It has been well tested in diverse teams and situation for multiple years now.\n> It's _super confusing_ when I `hg import` a patch and it seems to work but also immediately disappears, so I've got more sympathy for this PoC series than I do the theoretical purity of markers having any kind of globalness. Does that make sense?\nThis seems like an unrelated user interface issues. We usually warn the user when their working copy becomes obsolete, pointing out to the newest version\/evolution. We have to extend this messages logic to `hg import` to clarify the situation.\n","author":"lothiraldan","id":"70934","dateCreated":"1537368619","dateModified":"1537368619"},{"type":"comment","comment":">>! In D2679#68489, @lothiraldan wrote:\n> To take a step back, I'm wondering what's the end goal? I remember there was a discussion about having rebase enabled by default, is it related?\n\nGetting rebase (and maybe histedit?) enabled by default is my recollection of the rough goal.\n\n> \n> The behavior target by this series (\"unobsolete\" re-pulled changeset) conflicts with the final behavior we want for Changeset Evolution. Intermediate steps are a good way to make progress. I feel like it is important to write down a clear plan when it comes to adding behavior that does not match our final goals. How are we planning to transition from the local-only step to full (ie, distributed) Evolution?\n\nI'm slowly becoming convinced that the long-unquestioned axiom that \"all markers are distributed globally\" isn't correct, and this is part of why: it's potentially of great value to be able to restore a change by re-pulling it, even though the obsmarkers would normally cause it to be deleted. It's _super confusing_ when I `hg import` a patch and it seems to work but also immediately disappears, so I've got more sympathy for this PoC series than I do the theoretical purity of markers having any kind of globalness. Does that make sense?","author":"durin42","id":"69389","dateCreated":"1536762660","dateModified":"1536762660"},{"type":"comment","comment":"Hi Pulkit,\n\nThanks for your patience. I had a couple of important things to get out of the way before I could turn my attention to this.\n\nI reached out to Ryan and he sent me the code he wrote at the 4.6 Sprint. I made it available here to support the discussion: https:\/\/phab.mercurial-scm.org\/D4479. The core differences in his approach are to filter out obsmarkers affecting the \"re-pulled\" nodes instead of \"stripping\" those markers. The main benefit is to avoid information loss. Stripping markers will break the evolution history, preventing user to benefit from it. Filtering markers out mean that the history will be fully restored if the affected changeset get obsolete again. It can be triggered by the same events.This is a pure implementation detail, having the same user-level effect than the behavior proposed in this Proof of Concept series.\n\nRegarding the implementation of this series, I feel like the current detection code needs to move at a higher level. Having changegroup aware of obsmarkers at such a low level seems wrong and can lead to consistency issues if the bundle contains obsmarkers. An alternative approach would be to keep track of redundant incoming nodes during changegroup processing (on the transaction object as we are already doing for all new nodes), and process that list at the end of the transaction. We'll give a shot at such implementation, it is useful in other scenarios.\n\nTo take a step back, I'm wondering what's the end goal? I remember there was a discussion about having rebase enabled by default, is it related?\n\nThe behavior target by this series (\"unobsolete\" re-pulled changeset) conflicts with the final behavior we want for Changeset Evolution. Intermediate steps are a good way to make progress. I feel like it is important to write down a clear plan when it comes to adding behavior that does not match our final goals. How are we planning to transition from the local-only step to full (ie, distributed) Evolution?","author":"lothiraldan","id":"68489","dateCreated":"1536103480","dateModified":"1536103480"},{"type":"comment","comment":"Hey @lothiraldan, if not the patches itself, can you please explain the approach taken?\nIf I don't hear from you this week, I will push this series so that we can have enough time testing this in current cycle. Thanks!","author":"pulkit","id":"67297","dateCreated":"1535375938","dateModified":"1535375938"},{"type":"comment","comment":"@lothiraldan Gentle reminder for the series you were talking about.","author":"pulkit","id":"66824","dateCreated":"1534935417","dateModified":"1534935417"},{"type":"comment","comment":">>! In D2679#64079, @lothiraldan wrote:\n>>>! In D2679#62662, @pulkit wrote:\n>> These patches were result of a very extensive discussion about what ways we have to start supporting obsmarkers by default. I will like to push these changesets so that we can try these in this cycle. If I don't hear any concern in a week, I will push them.\n> \n> We made a series with Ryan during the sprint that had the advantage of not requiring to delete obs-markers. I will undust it, rebase it and send it here for making the discussion go forward.\n\nOh nice! That will be great! Looking forward to your series.","author":"pulkit","id":"64233","dateCreated":"1533639536","dateModified":"1533639536"},{"type":"comment","comment":">>! In D2679#62662, @pulkit wrote:\n> These patches were result of a very extensive discussion about what ways we have to start supporting obsmarkers by default. I will like to push these changesets so that we can try these in this cycle. If I don't hear any concern in a week, I will push them.\n\nWe made a series with Ryan during the sprint that had the advantage of not requiring to delete obs-markers. I will undust it, rebase it and send it here for making the discussion go forward.","author":"lothiraldan","id":"64080","dateCreated":"1533587987","dateModified":"1533587987"},{"type":"comment","comment":"These patches were result of a very extensive discussion about what ways we have to start supporting obsmarkers by default. I will like to push these changesets so that we can try these in this cycle. If I don't hear any concern in a week, I will push them.","author":"pulkit","id":"62663","dateCreated":"1533162260","dateModified":"1533162260"},{"type":"update","diffId":"6637","author":"indygreg","id":"43207","dateCreated":"1520210571","dateModified":"1520210571"}],"dateCreated":"1520210571","dateModified":"1579887165","status":"Needs Revision"},{"id":"5102","callsign":"HG","title":"beautifygraph: add configs for customizing the characters","author":"hooper","summary":"I figure we should keep this out of graphmod.py and templatekw.py for now.\nMoving the extension functionality out of hgext is a separate issue.\n\nCalling ui.config() inside getgraphnode seems like it might slow things down,\nbut it needs to happen there because of the template keyword. We probably want\nto honor config overrides, so we can't cache glyphs at this level.","testPlan":"","lineCount":"208","dependsOn":[],"reviewers":["baymax"],"ccs":["spectral","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117612","dateCreated":"1579887150","dateModified":"1579887150"},{"type":"reject","author":"baymax","id":"117611","dateCreated":"1579887150","dateModified":"1579887150"},{"type":"comment","comment":"I'll elaborate a bit. I think the idea of using unicode to make the graph good looking is flawed. There are no characters that properly serve common cases like this:\n\n```\no\n|\n \\\n o\n```\n\nThat's part of why there was some disagreement in early discussion of this extension.\n\nI think it's a bad user experience, because if the graph looks 95% like a connected drawing, these broken areas are going to look like malfunctions (whereas we started with a stylized ascii drawing where the limitations are obvious to the user).\n\nAdditionally, the existing graphlog output is lossy. The two pipes in this example do not have the same meaning:\n\n```\no\n|\n|\n \\\n o\n```\n\nEven if we had the unicode characters\/custom font needed to make this work, we would need at least 5 configurable variants of what is currently just a pipe. You would need hundreds of distinct characters to support all combinations of the 8 horizontal and diagonal edges in each character\/cell of the graph rendering. More than double that to support dashed lines. Maybe exclude some unused characters. It's hard to imagine making that easy to configure.\n\nYou can also imagine having the graphlog output optionally use only horizontal\/vertical edges so this can be done properly with box drawing characters. This is would complicate graphlog itself considerably, regardless of configuration.\n\nMeanwhile, this patch would be useful to some of our users, and it keeps the problems contained within the extension.","author":"hooper","id":"77628","dateCreated":"1540934965","dateModified":"1540934965"},{"type":"comment","comment":"hooper and I talked at the sprint, and they wrote up the following for why they feel we should keep this out of graphmod\/templatekw for now:\n\n> I don't think configurable graph log characters in core is a great idea right now, since it makes the empty promise that you can make logs look correct by using common fonts. E.g. the problem that pipe characters are used in several situations that just can't be handled well by one character.\n\nAs a specific example, there's no unicode line drawing characters that are fully-extended lines at 0 degrees (straight up) and 135 degrees (down to the right to the corner of the character box), so there will always be cases that can't really be represented \"perfectly\".\n\nI don't generally agree with this reasoning - limitations of unicode should not be a reason to require that we go through a separate extension like this. The reasoning for the extension instead of just making the actual graph characters customizable was two-fold, if I remember correctly:\n\n1. there is currently some awkward code to handle extending one of the characters used to draw parent\/grandparent lines for a few lines and then switch to the other. (https:\/\/www.mercurial-scm.org\/repo\/hg\/file\/tip\/tests\/test-glog.t#l3041 shows this in action) - the code to implement this is not unicode safe (at least in python2)\n2. the current graphlog code does not currently have config knobs to control every character, I think. \n\n\nI think we should fix the code issue in #1 (I just sent D5112 for this), and then we can extended graphlog to have whatever character(s) we need, instead of attempting to do the replacements in an extension like we're currently doing? The extension could just become a set of \"recommended\" values for these config knobs.\n","author":"spectral","id":"76474","dateCreated":"1539693777","dateModified":"1539693777"},{"type":"update","diffId":"12138","author":"hooper","id":"76357","dateCreated":"1539526671","dateModified":"1539526671"},{"type":"update","diffId":"12130","author":"hooper","id":"76302","dateCreated":"1539519730","dateModified":"1539519730"}],"dateCreated":"1539519730","dateModified":"1579887150","status":"Needs Revision"},{"id":"1701","callsign":"HG","title":"logtoprocess: add the possibility to not popup a console","author":"lothiraldan","summary":"Starting a subprocess on Windows with `DETACHED_PROCESS |\nCREATE_NEW_PROCESS_GROUP` as startup info means starting a console GUI window\nin almost all cases. If we add a logtoprocess for commandfinish and the prompt\ndo some hg calls, it will create a short-lived GUI window which is annoying\nfor end-users.\n\nCreating a subprocess with `CREATE_CONSOLE` instead seems to no start a\nconsole window but could have other side-effects so it kept under a config\nknob.","testPlan":"","lineCount":"13","dependsOn":["1700"],"reviewers":["baymax"],"ccs":["yuja","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117609","dateCreated":"1579887149","dateModified":"1579887149"},{"type":"reject","author":"baymax","id":"117608","dateCreated":"1579887149","dateModified":"1579887149"},{"type":"inline","comment":"Can we add `CREATE_NEW_PROCESS_GROUP` ?","replyTo":null,"isNewFile":"1","line":"66","lineLength":"0","path":"hgext\/logtoprocess.py","diffId":"4468","author":"yuja","id":"29101","dateCreated":"1513346507","dateModified":"1513346507"},{"type":"comment","comment":"> but could have other side-effects so it kept under a config knob.\n\nMy two cents, `experimental.*` might be better if the config knob exists as\na workaround for an unknown bug.","author":"yuja","id":"29100","dateCreated":"1513346507","dateModified":"1513346507"},{"type":"update","diffId":"4468","author":"lothiraldan","id":"29029","dateCreated":"1513332660","dateModified":"1513332660"}],"dateCreated":"1513332660","dateModified":"1579887149","status":"Needs Revision"},{"id":"5295","callsign":"HG","title":"branchmap: define a hasbranch() to find whether a branch exists or not","author":"pulkit","summary":"This patch introduces a branchmap.hasbranch() function to find whether a branch\nexists or not. I was going through profile of one of most used command\ninternally on server side and found that we are spending ~50% of time finding\nwhether a branch exists or not. We are reading the branchmap cache, building the\nrelated object and then finding whether a branch exists or not which is quite\nslow on repositories which have more than 10k named branches.\n\nIn the new function, we just iterate over the whole branchmap cache and find\nthat whether a branch name is present or not. This is essentially\nbranchmap.read() but without any hash validation, creation of the branchcache()\nobject.\n\nFollowing were the improvements observed:\n\nBefore:\n\n`hg log -b . -l 1`: 0.53 sec\n`hg log -b <last_branch_in_the_cache> -l 1`: 1.12 sec\n\nAfter:\n\n`hg log -b . -l 1`: 0.32 sec\n`hg log -b <last_branch_in_the_cache> -l 1`: 0.95 sec\n\n\nThere we no improvements observed in `hg log -r <branch_name>`, if the log limit\nis greater than 1, and while using revsets.\n\nI have added a TODO here that we can use binary search instead of plain\niteration for finding whether a branch name exists or not. I got to know that\nMartijn Pieters is working on some related stuff to load branchmap in memory as\nraw data and decided to implement binary search on top of that.","testPlan":"","lineCount":"29","dependsOn":[],"reviewers":["baymax"],"ccs":["yuja","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117606","dateCreated":"1579887147","dateModified":"1579887147"},{"type":"reject","author":"baymax","id":"117605","dateCreated":"1579887147","dateModified":"1579887147"},{"type":"comment","comment":"I don't think it's good idea to re-scan the cache file per hasbranch() call.\nInstead, we'll probably need a lazy parser backed by a in-memory cache data.\nThe current cache file format is text-based, which wouldn't be easily bisected\nwithout loading (or memmap) the whole content.\n\n> +def hasbranch(repo, branchname):\n> + \"\"\"check whether a branchname exists in the repo or not by reading the\n> + branchmap cache\"\"\"\n> +\n> + if not repo.cachevfs.exists(_filename(repo)):\n> + # branchmap file is not present, let's go repo.branchmap() route which\n> + # will create that file\n> + return branchname in repo.branchmap()\n> +\n> + # TODO: implement binary-search here for faster search\n> + with repo.cachevfs(_filename(repo)) as f:\n> + f = repo.cachevfs(_filename(repo))\n> + lineiter = iter(f)\n> + next(lineiter).rstrip('\\n').split(\" \", 2)\n\nNeed to check if the cache file is valid.\n\n> + for l in lineiter:\n> + l = l.rstrip('\\n')\n> + if not l:\n> + continue\n> + label = l.split(\" \", 2)[2]\n> + label = encoding.tolocal(label.strip())\n> + if label == branchname:\n\nAnd maybe need to check if the node exists.\n\n> + return True\n> + return False","author":"yuja","id":"78895","dateCreated":"1543118662","dateModified":"1543118662"},{"type":"update","diffId":"12582","author":"pulkit","id":"78822","dateCreated":"1542887394","dateModified":"1542887394"}],"dateCreated":"1542887394","dateModified":"1579887147","status":"Needs Revision"},{"id":"5308","callsign":"HG","title":"store: don't pass 'atomictemp=True' while appending to fncache","author":"pulkit","summary":"Appending to an atomictemp file means that the entire file is copied first.\nThanks to Yuya for suggesting.","testPlan":"","lineCount":"2","dependsOn":[],"reviewers":["baymax"],"ccs":["yuja","mjpieters","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117603","dateCreated":"1579887146","dateModified":"1579887146"},{"type":"reject","author":"baymax","id":"117602","dateCreated":"1579887146","dateModified":"1579887146"},{"type":"comment","comment":"> > As I said, we'll also need to somehow hide partial data from another\n> > reader processes. There's no read lock.\n> \n> \n> Read locks! was there a previous attempt on implementing them? I will try to take a shot at implementing them. I am unable to find any good detail except mentions in wiki or mailing list archive.\n\nAnother option is to ignore trailing data after `\\n`. That's how the revlog\nparser gets around partially-written entry.\n\nIn either way, writing fncache non-atomically wouldn't be strictly compatible\nwith older hg clients. I think that's okayish, but I should note that.","author":"yuja","id":"79385","dateCreated":"1543492790","dateModified":"1543492790"},{"type":"comment","comment":">>! Pasting Yuja's reply to that from mailing list:\n>>>! In D5308#78989, @pulkit wrote:\n>>>>! In D5308#78985, @yuja wrote:\n>>>> --- a\/mercurial\/store.py\n>>>> +++ b\/mercurial\/store.py\n>>>> @@ -486,7 +486,7 @@\n>>>> if self.addls:\n>>>> # if we have just new entries, let's append them to the fncache\n>>>> tr.addbackup('fncache')\n>>>> - fp = self.vfs('fncache', mode='ab', atomictemp=True)\n>>>> + fp = self.vfs('fncache', mode='ab')\n>>> \n>>> Ah, no. addbackup() creates hardlink, which means fncache can't be updated in\n>>> place. Also, the reader wouldn't handle partially-written fncache well.\n>> \n>> do we need to call `addbackup()` if we are just appending?\n>\n> We need a mechanism to restore the original content on rollback. IIUC,\n> it's `tr.add()` for append-only files.\n>\n> As I said, we'll also need to somehow hide partial data from another\n> reader processes. There's no read lock.\n\nRead locks! was there a previous attempt on implementing them? I will try to take a shot at implementing them. I am unable to find any good detail except mentions in wiki or mailing list archive.","author":"pulkit","id":"79002","dateCreated":"1543424805","dateModified":"1543424805"},{"type":"comment","comment":">>! In D5308#78985, @yuja wrote:\n>> --- a\/mercurial\/store.py\n>> +++ b\/mercurial\/store.py\n>> @@ -486,7 +486,7 @@\n>> if self.addls:\n>> # if we have just new entries, let's append them to the fncache\n>> tr.addbackup('fncache')\n>> - fp = self.vfs('fncache', mode='ab', atomictemp=True)\n>> + fp = self.vfs('fncache', mode='ab')\n> \n> Ah, no. addbackup() creates hardlink, which means fncache can't be updated in\n> place. Also, the reader wouldn't handle partially-written fncache well.\n\ndo we need to call `addbackup()` if we are just appending?","author":"pulkit","id":"78989","dateCreated":"1543326786","dateModified":"1543326786"},{"type":"comment","comment":"> --- a\/mercurial\/store.py\n> +++ b\/mercurial\/store.py\n> @@ -486,7 +486,7 @@\n> if self.addls:\n> # if we have just new entries, let's append them to the fncache\n> tr.addbackup('fncache')\n> - fp = self.vfs('fncache', mode='ab', atomictemp=True)\n> + fp = self.vfs('fncache', mode='ab')\n\nAh, no. addbackup() creates hardlink, which means fncache can't be updated in\nplace. Also, the reader wouldn't handle partially-written fncache well.","author":"yuja","id":"78986","dateCreated":"1543325866","dateModified":"1543325866"},{"type":"update","diffId":"12610","author":"pulkit","id":"78976","dateCreated":"1543324956","dateModified":"1543324956"}],"dateCreated":"1543324956","dateModified":"1579887146","status":"Needs Revision"},{"id":"2880","callsign":"HG","title":"bundle: add the possibility to bundle bookmarks (issue5792)","author":"lothiraldan","summary":"Also take the wlock when unbundling. It shouldn't have a big impact on\nperformance.","testPlan":"","lineCount":"143","dependsOn":[],"reviewers":["indygreg","baymax"],"ccs":["martinvonz","indygreg","pulkit","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117600","dateCreated":"1579887145","dateModified":"1579887145"},{"type":"reject","author":"baymax","id":"117599","dateCreated":"1579887145","dateModified":"1579887145"},{"type":"comment","comment":"Just a reminder that this has not been queued yet.","author":"martinvonz","id":"79389","dateCreated":"1543515570","dateModified":"1543515570"},{"type":"inline","comment":"I tried adding such scenarios but failed to produce a divergence scenario, no idea why.\n\nI don't think I will have time to debug the issue before the freeze, so let's skip this changeset for 4.6","replyTo":"53793","isNewFile":"1","line":"37","lineLength":"26","path":"tests\/test-bundle-bookmarks.t","diffId":"7077","author":"lothiraldan","id":"54248","dateCreated":"1523950897","dateModified":"1523950897"},{"type":"inline","comment":"I think it should be the same thing as pulling from another repo. Try putting the same changes in another repo and pulling from it without giving the path a name (nothing in [paths] config). I haven't checked what suffix will be used on the divergent bookmark, but it probably makes sense to use the same here (perhaps it's just going to be \"D1@1\" as I guessed before).","replyTo":"53729","isNewFile":"1","line":"37","lineLength":"26","path":"tests\/test-bundle-bookmarks.t","diffId":"7077","author":"martinvonz","id":"53793","dateCreated":"1523724103","dateModified":"1523724103"},{"type":"inline","comment":"I have added such test and indeed this case is not handled right now. I'm not aware of how Mercurial handle this case when exchanging bookmarks, I will need to take a look at the code to find out.\n\nWhat is the correct behavior here? Change the existing bookmark or the bookmark from the bundle?","replyTo":"46275","isNewFile":"1","line":"37","lineLength":"26","path":"tests\/test-bundle-bookmarks.t","diffId":"7077","author":"lothiraldan","id":"53729","dateCreated":"1523698843","dateModified":"1523698843"},{"type":"update","diffId":"8263","author":"lothiraldan","id":"53727","dateCreated":"1523698706","dateModified":"1523698706"},{"type":"comment","comment":">>! In D2880#52559, @indygreg wrote:\n> What's the status of this patch? Is it still reviewable? If so, let's get a rebased version submitted, just in case things have changed.\n\nI need to update the patch according to @martinvoz comment.\n\nI was also waiting on your comment on https:\/\/phab.mercurial-scm.org\/D2880#46263, do you think we will keep the option once the bundlespec system is revamped? If yes, we can make the config option a non-experimental one. But if it will be dropped soon, I think keeping it experimental until it's dropped is preferable. What do you think?","author":"lothiraldan","id":"52583","dateCreated":"1523555228","dateModified":"1523555228"},{"type":"comment","comment":"What's the status of this patch? Is it still reviewable? If so, let's get a rebased version submitted, just in case things have changed.","author":"indygreg","id":"52560","dateCreated":"1523549760","dateModified":"1523549760"},{"type":"reject","author":"indygreg","id":"52559","dateCreated":"1523549760","dateModified":"1523549760"},{"type":"inline","comment":"Can we have a similar test case where we create divergence? Create a fork in the graph in the debugdrawdag call above. Let's say you have commit F that branches off of B, then do something like this:\n\n```\n$ hg bundle --all bundle\n$ hg strip --no-backup C\n$ hg bookmarks -f -r F D1\n$ hg unbundle -q bundle\n$ hg log -G -T '{desc} {bookmarks}\\n'\n o E\n |\n o D D1 D2\n |\n o C\n |\n | o F D1@1\n |\/\n o B\n |\n o A A1\n```\n\nI don't know if \"@1\" is the appropriate divergence marker, but I can't think of a better one. I haven't even looked at your code to try to guess what it would be in practice (if it would work at all).","replyTo":null,"isNewFile":"1","line":"37","lineLength":"26","path":"tests\/test-bundle-bookmarks.t","diffId":"7077","author":"martinvonz","id":"46275","dateCreated":"1521218729","dateModified":"1521218729"},{"type":"inline","comment":"I was afraid we might have to delete this option once we have the discussion about bundle spec format with @indygreg. If that would be the case, I would feel more comfortable deleting an experimental option.\n\nIf we agreed on moving bundle-phases out of experimental, I guess we can do the same for bundle-bookmarks.\n\n@indygreg Do you think we would still have this option around once we have new-style bundle spec?","replyTo":"46262","isNewFile":"1","line":"422","lineLength":"0","path":"mercurial\/configitems.py","diffId":"7077","author":"lothiraldan","id":"46264","dateCreated":"1521208181","dateModified":"1521208181"},{"type":"inline","comment":"Any reason why we have all these config option as experimental? We talked at sprint about moving things out of experimental and we agreed on `experimental.bundle-phases`. This one sounds similar.","replyTo":null,"isNewFile":"1","line":"422","lineLength":"0","path":"mercurial\/configitems.py","diffId":"7077","author":"pulkit","id":"46262","dateCreated":"1521206865","dateModified":"1521206865"},{"type":"update","diffId":"7077","author":"lothiraldan","id":"46256","dateCreated":"1521206506","dateModified":"1521206506"}],"dateCreated":"1521206506","dateModified":"1579887145","status":"Needs Revision"},{"id":"5503","callsign":"HG","title":"vfs: add support for repo names with `$` when using with env vars (issue5739)","author":"navaneeth.suresh","summary":"`$ foo=bar hg root` fails to recognise the repo `$foo`. I stopped expanding env\nvars from vfs when there exists a repo with the same name as the env var.","testPlan":"","lineCount":"12","dependsOn":[],"reviewers":["baymax"],"ccs":["yuja","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117597","dateCreated":"1579887143","dateModified":"1579887143"},{"type":"reject","author":"baymax","id":"117596","dateCreated":"1579887143","dateModified":"1579887143"},{"type":"comment","comment":"> > This is logically incorrect. The problem is that we're doing variable\n> > expansion at too lower layer. `vfs(expand(user_specified_path))` makes\n> > some sense, but `vfs(expand(getcwd()))` is clearly wrong. And the vfs class\n> > can't know where the `base` comes from.\n> \n> If I add a condition for expanding env var if present in `hgrc`, can this work as a fix?\n\nMaybe no. Where do you intend to add such code? vfs doesn't know where the path\ncomes from. Neither does localrepo.\n\n> If the only solution for this is shifting path expansion from `vfs` class, where do you\n> think it can be?\n\nSomewhere specifying repository path read from hgrc or user input.","author":"yuja","id":"81826","dateCreated":"1547043138","dateModified":"1547043138"},{"type":"comment","comment":"> This is logically incorrect. The problem is that we're doing variable\n> expansion at too lower layer. `vfs(expand(user_specified_path))` makes\n> some sense, but `vfs(expand(getcwd()))` is clearly wrong. And the vfs class\n> can't know where the `base` comes from.\n\nIf I add a condition for expanding env var if present in `hgrc`, can this work as a fix?\nIf the only solution for this is shifting path expansion from `vfs` class, where do you\nthink it can be?","author":"navaneeth.suresh","id":"81684","dateCreated":"1546920534","dateModified":"1546920534"},{"type":"comment","comment":"> def __init__(self, base, audit=True, cacheaudited=False, expandpath=False,\n> realpath=False):\n> + if '$' in base and os.path.isdir(base):\n> + # when there exists a repo '$foo' and an env var foo=bar, stop\n> + # expanding path. refer issue5739.\n> + expandpath = False\n\nThis is logically incorrect. The problem is that we're doing variable\nexpansion at too lower layer. `vfs(expand(user_specified_path))` makes\nsome sense, but `vfs(expand(getcwd()))` is clearly wrong. And the vfs class\ncan't know where the `base` comes from.","author":"yuja","id":"81561","dateCreated":"1546867921","dateModified":"1546867921"},{"type":"update","diffId":"13046","author":"navaneeth.suresh","id":"81547","dateCreated":"1546862928","dateModified":"1546862928"},{"type":"update","diffId":"13025","author":"navaneeth.suresh","id":"81425","dateCreated":"1546850305","dateModified":"1546850305"}],"dateCreated":"1546850305","dateModified":"1579887144","status":"Needs Revision"},{"id":"5539","callsign":"HG","title":"style: run yapf on a subset of mercurial","author":"durin42","summary":"I've tried to pick knobs that more or less conform to our current\nstyle. I ran the formatter on the same set of files as the black\nproposal (see D5064), but it resulted in many fewer edits.","testPlan":"","lineCount":"171","dependsOn":[],"reviewers":["baymax"],"ccs":["mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117594","dateCreated":"1579887142","dateModified":"1579887142"},{"type":"reject","author":"baymax","id":"117593","dateCreated":"1579887142","dateModified":"1579887142"},{"type":"inline","comment":"We could force this to one-per-line by adding a trailing comma.","replyTo":null,"isNewFile":"1","line":"53","lineLength":"0","path":"mercurial\/scmwindows.py","diffId":"13110","author":"durin42","id":"81887","dateCreated":"1547066206","dateModified":"1547066206"},{"type":"inline","comment":"yapf bug here, filed as https:\/\/github.com\/google\/yapf\/issues\/662","replyTo":null,"isNewFile":"1","line":"57","lineLength":"1","path":"mercurial\/minifileset.py","diffId":"13110","author":"durin42","id":"81886","dateCreated":"1547066206","dateModified":"1547066206"},{"type":"comment","comment":"I see a few minor issues here, but it's at least plausible?","author":"durin42","id":"81885","dateCreated":"1547066206","dateModified":"1547066206"},{"type":"update","diffId":"13110","author":"durin42","id":"81877","dateCreated":"1547065732","dateModified":"1547065732"}],"dateCreated":"1547065732","dateModified":"1579887142","status":"Needs Revision"},{"id":"5566","callsign":"HG","title":"revlog: rename revlog I\/O classes to reflect version (API)","author":"indygreg","summary":"I never liked these names. They imply the existence of exactly\n2 revlog versions. We're hacking on version 2. So let's\nintroduce better names.","testPlan":"","lineCount":"14","dependsOn":["5565"],"reviewers":["baymax"],"ccs":["mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117591","dateCreated":"1579887140","dateModified":"1579887140"},{"type":"reject","author":"baymax","id":"117590","dateCreated":"1579887140","dateModified":"1579887140"},{"type":"update","diffId":"13162","author":"indygreg","id":"82190","dateCreated":"1547166758","dateModified":"1547166758"}],"dateCreated":"1547166758","dateModified":"1579887140","status":"Needs Revision"},{"id":"5567","callsign":"HG","title":"revlog: assign revlog._io in version lookup conditional","author":"indygreg","summary":"A single version lookup is desirable.","testPlan":"","lineCount":"9","dependsOn":["5566"],"reviewers":["baymax"],"ccs":["mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117588","dateCreated":"1579887139","dateModified":"1579887139"},{"type":"reject","author":"baymax","id":"117587","dateCreated":"1579887139","dateModified":"1579887139"},{"type":"update","diffId":"13163","author":"indygreg","id":"82200","dateCreated":"1547166761","dateModified":"1547166761"}],"dateCreated":"1547166761","dateModified":"1579887139","status":"Needs Revision"},{"id":"5495","callsign":"HG","title":"revset: add \"branch\" positional arguments to the merge revset","author":"angel.ezquerra","summary":"Make it possible to only include those merge revisions that are merges with one\nor more specific branches (passed as a positional argument that can receive\neither a single branch name or a regular expression). All merge revisions are\nshown by default (i.e. if no \"merge with\" branch or expression is specified).","testPlan":"","lineCount":"124","dependsOn":[],"reviewers":["baymax"],"ccs":["mharbison72","mjpieters","lothiraldan","pulkit","yuja","mercurial-devel"],"actions":[{"type":"comment","comment":"There seems to have been no activities on this Diff for the past 3 Months.\n\nBy policy, we are automatically moving it out of the `need-review` state.\n\nPlease, move it back to `need-review` without hesitation if this diff should still be discussed.\n\n:baymax:need-review-idle:\n","author":"baymax","id":"117585","dateCreated":"1579887138","dateModified":"1579887138"},{"type":"reject","author":"baymax","id":"117584","dateCreated":"1579887138","dateModified":"1579887138"},{"type":"comment","comment":"Thank you Matt. I just did that.\n\nCheers,\n\nAngel","author":"angel.ezquerra","id":"82634","dateCreated":"1547625859","dateModified":"1547625859"},{"type":"comment","comment":">>! In D5495#82416, @angel.ezquerra wrote:\n> I've sent an updated set of patches, following your recommendations. There are 2 patches now, since each includes its own tests. This means that the 3rd patch on the original patch set is no longer needed. However I don't know what is the best way to tell that to phabricator...\n\nI think you should be able to go to that 3rd patch, and set it to abandoned in the actions at the bottom.\n\n\n","author":"mharbison72","id":"82590","dateCreated":"1547618397","dateModified":"1547618397"},{"type":"comment","comment":">>! In D5495#82397, @yuja wrote:\n> Generally looks good.\n> \n> Can you fix a couple of nits? And if possible, fold the tests from D5577\n> into this and the next patch. We prefer including relevant test in each\n> commit.\n> \n>> -@predicate('merge()', safe=True)\n>> +@predicate('merge(withbranch)', safe=True)\n> \n> `merge([withbranch])` as it is an optional parameter.\n> \n>> def merge(repo, subset, x):\n>> - \"\"\"Changeset is a merge changeset.\n>> + \"\"\"Changeset is a merge changeset\n>> +\n>> + All merge revisions are returned by default. If a \"withbranch\"\n>> + pattern is provided only merges with (i.e. whose second parent\n>> + belongs to) those branches that match the pattern will be returned.\n>> + The simplest pattern is the name of a single branch. It is also\n>> + possible to specify a regular expression by starting the pattern\n>> + with \"re:\". This can be used to match more than one branch\n>> + (e.g. \"re:branch1|branch2\").\n>> \"\"\"\n>> # i18n: \"merge\" is a keyword\n>> - getargs(x, 0, 0, _(\"merge takes no arguments\"))\n>> + args = getargsdict(x, 'merge', 'withbranch')\n>> + withbranch = ''\n>> + if 'withbranch' in args:\n>> + withbranch = getstring(args['withbranch'],\n>> + _('withbranch argument must be a string'))\n>> + kind, branchname, branchmatcher = stringutil.stringmatcher(withbranch)\n> \n> Can you merge this with the next `if withbranch:` block to reduce the number\n> of conditionally defined variables referenced later?\n> \n>> cl = repo.changelog\n>> - return subset.filter(lambda r: cl.parentrevs(r)[1] != -1,\n>> - condrepr='<merge>')\n>> + # create the function that will be used to filter the subset\n>> + if withbranch:\n> \n>> + # matchfn is a function that returns true when a revision\n>> + # is a merge and the second parent belongs to a branch that\n>> + # matches the withbranch pattern (which can be a literal or a regex)\n> \n> Nit: these comments seem a bit verbose. It's documented in stringmatcher().\n> \n>> + if kind == 'literal':\n>> + matchfn = lambda r: (cl.parentrevs(r)[1] != -1\n>> + and repo[r].p2().branch() == withbranch)\n>> + else:\n>> + matchfn = lambda r: (cl.parentrevs(r)[1] != -1\n>> + and branchmatcher(repo[r].p2().branch()))\n> \n> If we don't have anything special about the `literal` kind, we can always use\n> the `branchmatcher()`. `if kind == 'literal'` isn't needed.\n\n\n\n>>! In D5495#82407, @yuja wrote:\n>> What about making the argument a revset instead of a branch name. You can get the same result `merge(branch(\"foo\")` but have a more expressive result `merge(only(4.8, 4.7))` ?\n> \n> That's basically a simpler form of my `filter()` proposal.\n> \n> The problem of `merge(branch(\"foo\"))` is that it's ambiguous which revision\n> the expression will be tested against. It could be expressed as\n> `merge(p2=branch(\"foo\"))` to disambiguate, but this syntax isn't generic\n> enough to express the `samebranch=True` constraint. So if we want a truly\n> expressive syntax, we'll need something like a lambda function.\n> \n> ```\n> filtereach(merge(), p2(_) & branch(\"foo\"))\n> filtereach(merge(), samebranch(parents(_))\n> ```\n> \n> I agreed with Angel in that `merge(withbranch=name)` would be useful enough\n> to have a dedicated syntax, but I'm open to other ideas like\n> `merge(p1=expr, p2=expr)`.\n\n@lothiraldan , your proposal is interesting but as @yuja said it is less generic that introducing a full blown filter function. Also, to be really flexible it would require some way to refer to the p2 revision (i.e. you'd need to introduce an implicit or explicit reference to each of the p1 or p2 revisions). I think this would make the syntax for the most common use cases that I want to cover too complex. That being said, the proposed syntax leaves open the door for introducing such revset based filtering in the future if needed (although I think that a generic filter function would be more useful).\n\n@yuja , I've sent an updated set of patches, following your recommendations. There are 2 patches now, since each includes its own tests. This means that the 3rd patch on the original patch set is no longer needed. However I don't know what is the best way to tell that to phabricator...","author":"angel.ezquerra","id":"82416","dateCreated":"1547509014","dateModified":"1547509014"},{"type":"update","diffId":"13210","author":"angel.ezquerra","id":"82413","dateCreated":"1547508400","dateModified":"1547508400"},{"type":"comment","comment":"> What about making the argument a revset instead of a branch name. You can get the same result `merge(branch(\"foo\")` but have a more expressive result `merge(only(4.8, 4.7))` ?\n\nThat's basically a simpler form of my `filter()` proposal.\n\nThe problem of `merge(branch(\"foo\"))` is that it's ambiguous which revision\nthe expression will be tested against. It could be expressed as\n`merge(p2=branch(\"foo\"))` to disambiguate, but this syntax isn't generic\nenough to express the `samebranch=True` constraint. So if we want a truly\nexpressive syntax, we'll need something like a lambda function.\n\n```\nfiltereach(merge(), p2(_) & branch(\"foo\"))\nfiltereach(merge(), samebranch(parents(_))\n```\n\nI agreed with Angel in that `merge(withbranch=name)` would be useful enough\nto have a dedicated syntax, but I'm open to other ideas like\n`merge(p1=expr, p2=expr)`.","author":"yuja","id":"82407","dateCreated":"1547472644","dateModified":"1547472644"},{"type":"comment","comment":"What about making the argument a revset instead of a branch name. You can get the same result `merge(branch(\"foo\")` but have a more expressive result `merge(only(4.8, 4.7))` ?\n\n(Sorry to be a bit late to the party) ","author":"lothiraldan","id":"82404","dateCreated":"1547468468","dateModified":"1547468468"},{"type":"comment","comment":"Generally looks good.\n\nCan you fix a couple of nits? And if possible, fold the tests from D5577\ninto this and the next patch. We prefer including relevant test in each\ncommit.\n\n> -@predicate('merge()', safe=True)\n> +@predicate('merge(withbranch)', safe=True)\n\n`merge([withbranch])` as it is an optional parameter.\n\n> def merge(repo, subset, x):\n> - \"\"\"Changeset is a merge changeset.\n> + \"\"\"Changeset is a merge changeset\n> +\n> + All merge revisions are returned by default. If a \"withbranch\"\n> + pattern is provided only merges with (i.e. whose second parent\n> + belongs to) those branches that match the pattern will be returned.\n> + The simplest pattern is the name of a single branch. It is also\n> + possible to specify a regular expression by starting the pattern\n> + with \"re:\". This can be used to match more than one branch\n> + (e.g. \"re:branch1|branch2\").\n> \"\"\"\n> # i18n: \"merge\" is a keyword\n> - getargs(x, 0, 0, _(\"merge takes no arguments\"))\n> + args = getargsdict(x, 'merge', 'withbranch')\n> + withbranch = ''\n> + if 'withbranch' in args:\n> + withbranch = getstring(args['withbranch'],\n> + _('withbranch argument must be a string'))\n> + kind, branchname, branchmatcher = stringutil.stringmatcher(withbranch)\n\nCan you merge this with the next `if withbranch:` block to reduce the number\nof conditionally defined variables referenced later?\n\n> cl = repo.changelog\n> - return subset.filter(lambda r: cl.parentrevs(r)[1] != -1,\n> - condrepr='<merge>')\n> + # create the function that will be used to filter the subset\n> + if withbranch:\n\n> + # matchfn is a function that returns true when a revision\n> + # is a merge and the second parent belongs to a branch that\n> + # matches the withbranch pattern (which can be a literal or a regex)\n\nNit: these comments seem a bit verbose. It's documented in stringmatcher().\n\n> + if kind == 'literal':\n> + matchfn = lambda r: (cl.parentrevs(r)[1] != -1\n> + and repo[r].p2().branch() == withbranch)\n> + else:\n> + matchfn = lambda r: (cl.parentrevs(r)[1] != -1\n> + and branchmatcher(repo[r].p2().branch()))\n\nIf we don't have anything special about the `literal` kind, we can always use\nthe `branchmatcher()`. `if kind == 'literal'` isn't needed.","author":"yuja","id":"82397","dateCreated":"1547435479","dateModified":"1547435479"},{"type":"update","diffId":"13204","author":"angel.ezquerra","id":"82387","dateCreated":"1547419518","dateModified":"1547419518"},{"type":"comment","comment":"> This would not make it possible to select multiple \"merged with\" branches by doing: hg log -r \"merge(feature1, feature2)\"\n> Instead I guess you are proposing that for that use case we force the user to do: hg log -r \"merge('re:(feature1|feature2)')\n> \n> Did I understand you correctly?\n\nYes. And we can introduce other prefixes of string matcher if `re:` seemed\nunnecessarily complex.\n\nEDIT: or introduce `merge(withbranch=(foo, bar))` syntax. This works, but is really new\nsyntax so I don't want to go this way at this point.","author":"yuja","id":"82310","dateCreated":"1547259824","dateModified":"1547260148"},{"type":"comment","comment":">>! In D5495#82036, @yuja wrote:\n>> I think it would be a good idea to make the \"branch\" arguments more flexible. One option could be to use a stringmatcher to add support for regular expressions as you suggest. I can look into that. However there may be some other options worth exploring. The one you suggest is very interesting although I find the syntax a bit complicated for the common use cases that I want to enable which are:\n>> \n>> 1. Ignore merges from the same branch, which in a named-branch based branching strategy are usually irrelevant\n>> 2. Look into merges with a specific branch (e.g. which branches have been merged with the default branch)?\n>> \n>> In my experience those two are the ones that are the most common and I think we should try to make the easy to use. That is, I think that even if mercurial had a filter function like the one you propose I would still want to be able to express those 2 common merge properties in a simple way.\n> \n> Yep, I agree with that.\n> \n>> That being said, I really like your idea since I often find myself being unable to express what I want with a revset (as powerful as those are) because of the lack of a filtering mechanism. Adding a generic filter function would be very useful indeed. I'm not sure if the syntax you propose would work as is though. It seems that it would need a new \"&\" operator? In any case I believe that it is out of the scope of this particular set of patches. Do you agree?\n> \n> Yes. Actually I have a PoC-level implementation of generic filtering predicate,\n> which can be reviewed separately.\n> \n>> If so I can focus on improving this patch by adding the stringmatcher as you suggest (as it seems I'm not the only one who thinks this would be useful). Is that ok?\n> \n> Sounds good to me. To be clear, I want `'withbranch'` instead of\n> `'*withbranch'`, because the withbranch option doesn't look like a first-class\n> parameter of the `merge()` predicate.\n\nThis would not make it possible to select multiple \"merged with\" branches by doing: hg log -r \"merge(feature1, feature2)\"\nInstead I guess you are proposing that for that use case we force the user to do: hg log -r \"merge('re:(feature1|feature2)')\n\nDid I understand you correctly?","author":"angel.ezquerra","id":"82291","dateCreated":"1547248200","dateModified":"1547248200"},{"type":"comment","comment":"> I think it would be a good idea to make the \"branch\" arguments more flexible. One option could be to use a stringmatcher to add support for regular expressions as you suggest. I can look into that. However there may be some other options worth exploring. The one you suggest is very interesting although I find the syntax a bit complicated for the common use cases that I want to enable which are:\n> \n> 1. Ignore merges from the same branch, which in a named-branch based branching strategy are usually irrelevant\n> 2. Look into merges with a specific branch (e.g. which branches have been merged with the default branch)?\n> \n> In my experience those two are the ones that are the most common and I think we should try to make the easy to use. That is, I think that even if mercurial had a filter function like the one you propose I would still want to be able to express those 2 common merge properties in a simple way.\n\nYep, I agree with that.\n\n> That being said, I really like your idea since I often find myself being unable to express what I want with a revset (as powerful as those are) because of the lack of a filtering mechanism. Adding a generic filter function would be very useful indeed. I'm not sure if the syntax you propose would work as is though. It seems that it would need a new \"&\" operator? In any case I believe that it is out of the scope of this particular set of patches. Do you agree?\n\nYes. Actually I have a PoC-level implementation of generic filtering predicate,\nwhich can be reviewed separately.\n\n> If so I can focus on improving this patch by adding the stringmatcher as you suggest (as it seems I'm not the only one who thinks this would be useful). Is that ok?\n\nSounds good to me. To be clear, I want `'withbranch'` instead of\n`'*withbranch'`, because the withbranch option doesn't look like a first-class\nparameter of the `merge()` predicate.","author":"yuja","id":"82036","dateCreated