msg170263 - (view) |
Author: Ezio Melotti (ezio.melotti) *  |
Date: 2012-09-11 05:13 |
The attached Mercurial hook checks that all the changesets in a 3.x branch are merged with either another cset in the same branch or a cset in the following 3.x branch. This is to detect and prevent situations where people commit something on e.g. 3.2 and push it without merging it with default. |
|
|
msg170289 - (view) |
Author: Jesús Cea Avión (jcea) *  |
Date: 2012-09-11 11:06 |
We need something like this. I can not review, I am not familiar with mercurial hooks internals. |
|
|
msg170292 - (view) |
Author: Christian Heimes (christian.heimes) *  |
Date: 2012-09-11 11:59 |
+1 for the feature |
|
|
msg170309 - (view) |
Author: Ezio Melotti (ezio.melotti) *  |
Date: 2012-09-11 14:39 |
Attached a set up script to reproduce a test environment for the hook. Create an empty dir and run ``sh setup.sh`` in it. This will: 1) create a 'c1' subdir which is a cpython-like repo with the branches 2.7, 3.1, 3.2, default; 2) download and set up the hook for this repo; 3) create a 'c2' clone of 'c1'; Once the clones are created, cd in 'c2', try to commit something, and push it. Use `hg up ` to switch between branches. If you `hg up 3.1`, change something, commit, and push, the hook will tell you that you have to merge with 3.2, if you do the same on 3.2 it will say you have to merge with default. You can try unusual combinations (e.g. null merges, rollbacks, multiple commits per branch, etc.) to see how well the hook works. |
|
|
msg170315 - (view) |
Author: Antoine Pitrou (pitrou) *  |
Date: 2012-09-11 15:32 |
I might be wrong, but the logic in your hook looks a bit complicated. Wouldn't it be simpler to find all topological heads in the new csets (a topological head is a cset without any child), and check that none of them is on a 3.* branch? Finding topological heads is very easy, so http://hg.python.org/hooks/file/72aaeb80a55a/checkwhitespace.py#l85 |
|
|
msg170319 - (view) |
Author: Ezio Melotti (ezio.melotti) *  |
Date: 2012-09-11 16:02 |
> I might be wrong, but the logic in your hook looks a bit complicated. This might be true. The logic I followed is that once a cset is merged, it becomes a parent of another cset (either in the same branch or in the "next" one). So, if the cset is in 3.x and is not a parent, it should be merged. > Wouldn't it be simpler to find all topological heads in the new csets > (a topological head is a cset without any child), and check that none > of them is on a 3.* branch? If it's not a parent, it also means that it doesn't have any child, so we are looking at the same thing from two different points of view. If I'm reading the code you linked correctly, it's adding all the incoming changesets in a set, and for each changeset added to the set, all its parent are removed, so that eventually only the childless changesets (the topological heads) are left. This should also be equivalent to "set(allcsets) - set(allparents)". On the other hand my code checks for specific branches, so if you commit on 3.1 and merge on default, the cset in 3.1 is not a topological head so it's not detected by the version you linked, whereas my script will complain saying that it should be merged with 3.2 and then with default (even if maybe it should complain because you merged it in the wrong branch). |
|
|
msg184139 - (view) |
Author: Senthil Kumaran (orsenthil) *  |
Date: 2013-03-14 07:26 |
Reviewed the patch - the logic looks okay to me - namely verifying that the changeset the merged with the next +0.1, 3.x branch or default. I tested. 2.7 -> push -> success. 3.1 -> push -> fail -> merge to 3.2 -> fail -> merge to default -> success. Looks like a good server-side hgrc hook to have. |
|
|
msg184361 - (view) |
Author: Terry J. Reedy (terry.reedy) *  |
Date: 2013-03-16 23:53 |
+1 Would it be easy to check that no 2.7 commit is merged with anything in another branch? (I have not seen anyone do such a wrong merge, but I expect it will happen someday.) |
|
|
msg184362 - (view) |
Author: Ezio Melotti (ezio.melotti) *  |
Date: 2013-03-16 23:57 |
It happened once already. It shouldn't be too difficult to add, but it might make the code more complicated and more likely to fail in some situation. |
|
|
msg184980 - (view) |
Author: Ezio Melotti (ezio.melotti) *  |
Date: 2013-03-22 16:07 |
> Wouldn't it be simpler to find all topological heads in the new csets > (a topological head is a cset without any child), and check that none > of them is on a 3.* branch? Indeed -- I was looking at this again and it occurred to me that checking that the only two topological heads are 2.7 and default would be simpler, which is basically the same thing you were suggesting. I couldn't find a way to get the list of topological heads on active and non-closed heads using the `hg *` commands, but it shouldn't be difficult to do it from the API. FWIW, `hg heads --topo` also includes closed heads that have never been merged with the other branches (e.g. 2.0, 2.1, etc.). `hg branches` lists all the non-closed branches, and, among them, the one that are not "inactive" should be the ones with a topological head. Therefore this should boil down to either a set intersection between open branches and topological heads, or a set difference between open branches and inactive branches. Once the hook detects an extra head, it could try to figure out what's wrong and suggest a solution. |
|
|
msg184993 - (view) |
Author: Martin v. Löwis (loewis) *  |
Date: 2013-03-22 17:41 |
hg log -r 'head()-parents(merge())-closed()' --template '{branch}\n' works for me. Alternatively, hg log -r 'head()-parents(merge())-closed()-branch(2.7)-branch(default)' should come out empty. |
|
|