Could someone please explain why my preoutgoing hook gets executed on doing hg strip (Mercurial Strip)? Is there any chance to disable that behavior?
I'd expected the hook to run when doing hg push.
To avoid the execution of my hook code, I've added the following lines of code to the very beginning of my hook:
if "%HG_SOURCE%" == "strip" (
exit /b 0
)
Both outgoing and preoutgoing will be provided with a parameter indicating the source action. In Python, this parameter is called source, otherwise you can access the environment variable HG_SOURCE:
hg push → HG_SOURCE is push
hg strip → HG_SOURCE is strip
Based on that observation, you can simply evaluate the initial command.
Sources:
preoutgoing
Sources of changesets
Related
Sometimes developers on my team forget to pull in other developer's changesets before committing their own (admittedly, I do this as well). For a week long project there could be dozens of changes in the tree that the new commit skips over. When trying to push, hg aborts with the new remote head message then they pull and merge in all those new commits. What I'm looking for is an easy way to test if there are any new changes before someone commits and if there are to prevent the commit from happening. Ideally, there would be a clear message stating why the commit failed.
This seems like it should be very easy for a hook to accomplish but the pre-commit hook will continue on a status code of 0 and hg incoming will return 1 when there are no changes. All I need to do is invert the status of the hg incoming command but I can't find the syntax to do it. Most of the search results that I've found dive right into writing python hooks but that seems like overkill for such a simple problem.
I'm looking for something like this:
[hooks]
pre-commit != hg incoming
or
pre-commit = hg incoming == 0
I'm not sure where the message would go, either.
On Windows you can use this command to check for incoming changes:
[hooks]
pre-commit.checkNew = CMD /V /C "hg incoming & IF !ErrorLevel! EQU 0 (Exit 1) Else (Exit 0)"
If new changes are found it will cancel the commit and you will need to pull (and possibly merge) the new changes.
You had it mostly right, but you got the hook wrong:
[hooks]
precommit = ! hg incoming
There's no dash in the hook that can cancel the commit.
If, however, you turn a DVCS system into something where people can't commit without being connected to the internet your coworkers will string you up. :)
I found a solution by rereading the docs again: control if hook can proceed. Where I found the grep command in use.
[hooks]
precommit.comment = REM Don't forget to pull first!
precommit.test = hg incoming | grep -q "no changes found"
When a developer gets a failed commit they can check the output log and see the note. Not too pretty but should suffice most of the time. -q prevents "no changes found" from appearing in the log which would be confusing after a failed commit. I added my own extensions .comment and .test so the hooks get run in the correct order (c before t).
We have a simple mercurial hook that runs every time we pull remote changes. We use changegroup hook. Our hook rebuilds some dlls and copy them to a folder. We automatically rebase when we do a pull. This causes our hook to be run two times, first when we do the pull, then after the automatic rebase.
Is there any easy way to detect if there's going to be a rebase and only run the hook once at the end of the rebase?
Thanks,
Could you show your original hook?
Anyway, if you check the source parameter, you could choose if the hook should run or not:
def changegroup_hook(ui, repo, source, **kwargs):
if source != 'strip': # rebase operation uses 'strip' as source
return 0 # SUCCESS
# continue rebase processing
I currently have a pre-commit hook in my mercurial project that gives the user the option to update the version number of the project if they wish (e.g. 1.0 to 1.0.1 or 1.1 or 2.0). They select one of these options, and the hook updates the version number in one of the project's files prior to the commit taking place.
When I run hg commit, this hook runs and updates the relevant file with the new version number, and then performs the commit.
I'd like to add to the hook such that it calls hg tag <new_verson_number> as well.
However, I can't add this to the pre-commit hook, because then the tag will be added before the commit is called, causing the tag to be one revision out of date.
I'd like to add the hg tag command to a commit hook (run after the commit), so that the sequence of events is like so:
hg commit -m "my commit message"
user says yes, I'd like to change the version number
version number is updated in the relevant file
commit occurs [everything up to here is fine]
if the user changed the version number, run a commit hook: hg tag <new_version_number>.
Now, I could add a commit hook that read off the new version number from the file it's stored in and run hg tag <new_version_number>, but what if the user decided not to change the version number? In that case, I don't want a tag added, and if I blindly run hg tag <new_version_number> I'll end up with tags I don't want.
So - is there some way I can tell the pre-commit hook to leave some information for the commit hook (a yes/no of whether to add the tag), and the commit hook can use this to determine whether to add the tag or not?
cheers.
How about a commit hook that checks if the last commit modified the file in which you store the version? Something like:
[hooks]
commit.tagversion = if hg log -r $HG_NODE --template '{files}' | grep -q VERSION_FILE ; then hg tag $(hg cat -r $HG_NODE VERSION_FILE) ; fi
I haven't tested it, but that or something like it should work.
You could extract the tag name that you would add and then check to see if it already exists in hg tags before you add it. That would also catch the case where the developer amends the version number manually.
I've been using Zsh as a Bash replacement for a while now. One thing that doesn't work as well anymore is the completion for branch and uncommitted file names for mercurial.
If previously (bash) I had the following hg tracked folder:
repo/
.hg/
file1.txt
file2.txt <-- modified
Then doing this in Bash:
% hg commit -m "changed file2.txt" <TAB>
automagically completed file2.txt.
Same with branches — assuming I had default, dev and crazy branches, Bash knew how to complete branch names:
% hg update cr<TAB>
completed the branch name to crazy.
Basically what I'm asking is how to restore this functionality — which file/s take care of that and so on.
zsh uses its internal system for advanced completion, while bash uses a separate bash-completion software for that. Their configuration is incompatible so if you want some function to work you need to find a 3rd party zsh completion module for it or write it yourself. mercurial contains a sample zsh completion function, it is installed on my system as /usr/share/doc/mercurial/examples/zsh_completion.gz.
Being very familiar with the subversion workflow and that fact that 99.9% of the time my computer is connected to the internet, I don't like doing 'hg ci' and 'hg push' separately.
I remember bzr had a 'checkout' command that would bind subsequent 'commit' commands to automatically commit directly to the server ('push').
Does mercurial have something similar to this?
PS: Writing a shell script or alias that runs 'hg ci $* && hg push' would be the last thing I'd do.
You could add a hook to run push after a successful commit.
EDIT: I just tried it out and it seems to work fine. I added the following to the .hg/hgrc file of the repository I wanted to activate automatic pushing for:
[hooks]
commit.autopush = hg push
EDIT 2: Also, you don't have to worry about something like this:
You're in a repository that you don't want to automatically push.
You use hg -R ~/another-repo-that-autopushes commit to commit in a different repo that does automatically push.
Will the hg push hook end up pushing the changes in the current directory instead of the one you're committing in?
No, it won't. According to the page I linked:
An executable hook is always run with its current directory set to a repository's root directory.
It's an edge case, but Mercurial handles it correctly.