Useful TortoiseHg extensions - mercurial

Guys, could you please describe TortoiseHg extensions which comes with the installation package? What do these do and which you use on the daily basis? What are more useful?
This is the list from TortoiseHg v1.1.5 for Windows.
[extensions]
; extensions shipped with Mercurial by default
;
;acl =
;bookmarks =
;bugzilla =
;children =
;churn =
; Warning: the color extension is not recommended for Windows
;color =
;convert =
;extdiff =
;fetch =
;gpg =
;graphlog =
;hgcia =
;hgk =
;highlight =
;interhg =
;keyword =
;mq =
;notify =
;pager =
;parentrevspec =
;patchbomb =
;progress =
;purge =
;rebase =
;record =
;schemes =
;transplant =
;win32mbcs =
;win32text =
;zeroconf =
; Extra extensions bundled with TortoiseHg
;fold =
;hgcr-gui =
;perfarce =
;hgeol =
;mercurial_keyring =

My personal favorites:
graphlog ASCII graph next to changesets to visualize branching.
mq Handle local changes as a series of patches that can be edited.
purge Mass delete of unrevisioned files (and ignored files with --all).
rebase transplant a branch onto a different changeset.
transplant Copy a changeset onto the local changeset.
Of these, I use mq and purge daily.

After one year of experience I have gained my own must-have list of most useful mercurial extensions (using Windows and TortoiseHg). Will list in the order of importance.
mq (for history edition and rebase become enabled)
rebase (for changes movements around repo)
transplant (sometimes needed for precise control of changesets)
bookmarks (rarely needed to mark a head of a branch)

the color extension made me curious so here is what the docs say for it:
This extension modifies the status command to add color to its output to reflect file status, the qseries command to add color to reflect patch status (applied, unapplied, missing), and to diff-related commands to highlight additions, removals, diff headers, and trailing whitespace.
Other effects in addition to color, like bold and underlined text, are also available. Effects are rendered with the ECMA-48 SGR control function (aka ANSI escape codes). This module also provides the render_text function, which can be used to add effects to any text.

Related

HG command line input receives unwanted default input automatically in THG

I've written an Hg hook (in Python) to check the validity of the committed files according to out team rules. One of these rules prohibits files larger than XX kB, unless agreed with the ream. In case a large file is committed, I would like the hook to ask the user to allow the file.
I implemented it like this:
import re, os, sys, mercurial
MAX_SIZE_KB = 500
def check_committed_files(ui, repo, **kwargs):
changelog = repo.changelog._cache
lines = changelog[2].splitlines()
ui.status("Checking files...\n")
for line in lines[3:-2]:
fn = line
ui.status(" " + fn)
# check file size
file_size_kb = float(os.stat(line).st_size) / 1024
if file_size_kb > MAX_SIZE_KB:
if ui.prompt(" Allow file [%s] of %g kB?" % (fn, file_size_kb)).lower() not in ['y', 'yes']:
ui.warn(" Not allowed by user\n")
return 1
ui.flush()
return 0
It all works well if I use Hg CLI. But when I use TortoiseHg, the prompt is automatically yes-ed, so I get this in console:
Allow file [test.txt] of 2573.49 kB? y
and the hook goes on. I would like TortoiseHg to show a dialogue with Yes/No buttons. Is it possible? I'd like to have the solution as portable as possible, so e.g. no external Python modules that users need to install.
Since this is my first attempt with Hg hooks, any other comments on my implementation are also much appreciated.

Mercurial: TortoiseHg configuration to always prompt for manual resolve for all files when merging

We use Mercurial via TortoiseHg with the 'workbench'.
When merging branches, we often find the default (auto?) choice of updates is not what we want. We'd like to configure the tool to always prompt for any merge operation.
Each branch has some core files that we need to keep up to date between the two, but also some branch-specific files which need to be preserved.
If we update the core files in one branch we'd like to do a merge to get the latest core files in the other branch. However the default TortoiseHg makes automatic updates that we don't want.
Examples:
1) Branch '1' contains a file '1.xls' and branch '2' has an equivalent '2.xls' which are stored as binary. Merging '1' into a working directory based off '2' causes a delete of '2.xls' and an add of '1.xls'.
2) Branch '1' contains an updated file 'not_core.c' which has an equivalent 'not_core.c' in branch '2'. Merging '1' into a working directory based off '2' causes an unwanted automatic update of 'not-core.c' in '2'.
3) Branch '1' contains updated files 'core1.c' & 'core2.c'. Merging '1' into a working directory based off '2' causes an automatic update of both files, when we'd prefer a prompt to allow us to chose if these core files are updated. Maybe we want just 'core1.c' for now.
I have seen reference to setting 'mergetool.premerge = false' in mercurial.ini, and have tried some variants of this without success.
The ideal setup would be that the graphical manual resolve is triggered for every file that is different.
Can anyone help with a configuration that supports the functionality described?
Thanks, Ian
Three described cases have different nature in you case, you have to use different tricks for different cases
Cases 2 and 3 (non-conflicting changes in files of ranches) can be covered (TBT!) by disabling auto-merges in TortoseHG (Main menu - File - Settings - Global setting - TortoiseHG - "Auto-resolving merges": False /default - True/)
For case 1 (and other non-content changes - renames, changing attributes) situation is worse and automerge doesn't play: merge mirror history of changes from one branch to another, i.e if in common parent you have only 2.xls, which was deleted|renamed to 1.xls in source branch this change will be reflected in target.
You can try to use different "internal" merge-tool in such merges (when your prefer changes only from one branch - "dummy merge") - internal:local and internal:other. But - they work only for changed content (again!)
Maybe Keep "My" or "Their" files when doing a merge from TipsandTricks section will help (you can join mentioned merge-revert-resolve into new command in [aliases] and use it instead of ordinary merge, when needed)
You can configure this using the merge-patterns and merge-tools sections of hgrc. This set up allowed me to force kdiff3 to be used in my test:
[merge-patterns]
** = noautomerge
[merge-tools]
noautomerge.executable = kdiff3
noautomerge.args = $base $local $other -o $output --qall
noautomerge.priority = 1
noautomerge.premerge = False
This will turn off the automatic pre-merge that Mercurial does and start up kdiff3 instead.
It will do it for all files but it you might be better to amend the merge-patterns section to be a little more specific if that is possible.
Also, be aware of the possibility that your merge tool might automatically resolve the merge itself and if that happens look for command line options to turn that feature off.

mercurial keywords not expanding in js and css files

I am on Windows 7 using TortoiseHg 2.1.3 and I have configure it to use the keyword extension (please, no "it is bad practice" remarks, I have studied the arguments and I think in my case it is a valid use).
My mercurial.ini file looks like this:
[ui]
username = xxx
merge =beyondcompare3
ignore = ~/.hgignore
[tortoisehg]
vdiff =beyondcompare3
engmsg = True
ui.language = en
[extensions]
mercurial_keyring =
keyword =
convert =
[keyword]
*.css =
*.js =
*.php =
*.html =
*.htaccess =
[keywordmaps]
Id = {file|basename} {rev}.{node|short} {date|utcdate} {author|user}
Revision = {desc}
Now in any php, html and htaccess file my $Id$ gets expanded as expected when I commit the file, but in any js and css file they do not?
I am at a loss as to understand why, in all files, the document header is the same (I use a template for that which has the $Id$ in it).
Side note:
File-mask pattern for keyword section (and for other parts, where they used) must be **. (not Win-pattern with one star, but two). Sometimes for some filenames it can play
For the ID expansion I'll try probably to create clone of this keyword and test inside problem file-types (don't forget kwshrink|kwexpand magic words), catch differences after tests

How to configure Mercurial to use Kompare when merging?

I've tried adding merge=kompare to my ~/.hgrc, but when I run hg merge, it runs kompare, but there's no UI to be seen. Hg says merging path/to/first-file and stays there, actionless.
The kompare.args posted earlier probably wont work. I've had difficulty using Kompare for merging, especially 3-way merges (which are preferred and safe).
BTW, most of the other options are enabled by default I believe, but you can verify with: hg showconfig merge-tools
You are better off using kdiff3. Incase you are on Ubuntu Intrepid, kdiff3 was erroneously removed from the repos - but you can easily compile from source.
You will also need to add a section that explains how to call Kompare. I don't know Kompare, so I don't know what the command line should look like (no guarantees for the kompare.args line), but it should be something like this:
[merge-tools]
kompare.executable = C:\<path...>\kompare.exe
kompare.args = $base $local $other -o $output
kompare.priority = 1
kompare.gui = True
kompare.binary = True
If merges aren't detected correctly, you might want to add
kompare.checkconflicts = True
kompare.checkchanged = True
Kompare does not support 3-way diffs, so it can be used for Visual Diff feature only. Here's the config to make it work:
[merge-tools]
kompare.executable = kompare
kompare.diffargs = -c $parent $child
kompare.gui = True
Note the diffargs field instead of args.

Case-insensitive diffs in Mercurial

I'm using Mercurial (specifically TortoiseHg on Windows) to do version control of VBA code. Anybody who's tried this knows that VBA changes the case of every variable throughout a project whenever any declaration of that variable is changed anywhere in the project (regardless of scope). It makes version control a nightmare.
I would like to ignore case changes in my source code when performing diffs. What is the easiest way to do this? (some option for diff that I'm missing, an external diff utility, something else?)
NOTE: I am not talking about dealing with 'case-insensitive filenames' (yes, I'm talking to you Google...)
You can do that when diffing for your on-screen consumption using the ExtDiff Extension.
[extensions]
hgext.extdiff =
[extdiff]
# add new command that runs GNU diff(1) in case-insensitive mode
cmd.mydiff = diff
opts.mydiff = -i
Then you'd run hg mydiff from the command line. That, of course, requires you have a diff binary installed be it gnu's or other.
However, that's not going to be as helpful as you might like because internally, of course, Mercurial can't ignore case -- it's taking the cryptographic hash of the file contents, and those don't allow for wiggle room. So if you get this set up you'll do hg mydiff, and see no changes, and then do hg commit and see changes all over the place.
So you can make this work on-screen, but not fundamentally.
One option would be to find a visual basic code-cleaner, similar to indent for C-like languages, that normalizes variable case and run that in a mercurial commit hook. Then at least all the code going into source control will be consistent and you can diff across revisions accurately.
If you are okay with having your code in all lower-case, say, then you could employ the encode/decode hooks for this. It would work like this:
[encode]
*.vba = tr A-Z a-z
This will encode the file content in lower-case whenever you do a commit. The diffs are also computed based on the encoded (repository) version of the files.
Consider a file that contains
hello
Changing it in your working copy to
Hello World
will give a diff of
% hg diff
diff --git a/a.txt b/a.txt
--- a/a.txt
+++ b/a.txt
## -1,1 +1,1 ##
-hello
+hello world
Notice how the capital "H" and "W" has been ignored.
I don't really know anything about VBA code, so I'm not 100% sure this solution works for you. But I hope it can be a starting point.
One drawback is that you'll need to set this encode rule for all your repositories. The reposettings extension can help you here.
Here's the solution I have settled on. It is far from ideal, but better than the other alternatives I've considered.
I created an Autohotkey script that does the following:
reverts MS Access files in a repository with detected changes (to .orig files)
reads in the .orig file (the one with the changes)
reads in the existing file (the one already in the repository)
converts the text of both files to lower case
compares the lower case contents of the files
if the files still differ, the .orig file is restored so it may be committed to the repository
if the files are the same (i.e., they differ only in case, the .orig file is deleted because we don't care about those changes)
For files that have actual changes that we care about, I still see the case changes that were made as well. If that results in a lot of noise, I open the file in a comparison tool that allows case-insensitive compares (e.g., kdiff).
It's not a perfect solution, but it removes about 90% of the frustration for me.
Here's my script. Note that the script includes another Autohotkey script, ConsoleApp.ahk, which provides a function named, ConsoleApp_RunWait(). This is a 3rd party script that no longer works very well with 64-bit AHK, so I'm not including it as part of my answer. Any AHK function that executes a command line and returns the output as a string will suffice.
; This script checks an MS Access source directory and reverts all files whose only modifications are to the
; case of the characters within the file.
#Include %A_ScriptDir%\ConsoleApp.ahk
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
; Allow for custom path to hg (support for moving to TortoiseHg 2.0)
IniRead hg, %A_ScriptDir%\LocalSettings\Settings.cfg, TortoiseHg, hg_path, hg
if 0 < 1 ; The left side of a non-expression if-statement is always the name of a variable.
{
MsgBox Usage:`n`HgIgnoreCase DirectoryWithFilesToScrub
ExitApp
}
SrcDir = %1%
StringReplace SrcDir, SrcDir, ", , All
StringRight test, SrcDir, 1 ; add trailing slash if necessary
ifnotequal test, \
SrcDir = %SrcDir%\
RestoreOriginals(SrcDir)
RevertCaseChangeModifiedFiles(SrcDir)
RevertCaseChangeModifiedFiles(SrcDir) {
global hg
includes = -I "*.form" -I "*.bas" -I "*.report" -I "*.table"
cmdline = %hg% revert --all %includes%
;Don't revert items that have been removed completely
Loop 3
{
Result := ConsoleApp_RunWait(hg . " status -nrd " . includes, SrcDir)
If (Result)
Break
}
Loop parse, Result, `n, `r
{
if (A_LoopField)
cmdline = %cmdline% -X "%A_LoopField%"
}
Result =
;msgbox %cmdline%
;revert all modified forms, reports, and code modules
Loop 3
{
Result := ConsoleApp_RunWait(cmdline, SrcDir)
If (Result)
Break
}
;MsgBox %Result%
Loop parse, Result, `n, `r
{
StringLeft FileStatus, A_LoopField, 9
If (FileStatus = "reverting")
{
StringMid FName, A_LoopField, 11
FullPath = %SrcDir%%FName%
ToolTip Checking %FullPath%
RestoreIfNotEqual(FullPath, FullPath . ".orig")
}
}
ToolTip
}
RestoreIfNotEqual(FName, FNameOrig) {
FileRead File1, %FName%
FileRead File2, %FNameOrig%
StringLower File1, File1
StringLower File2, File2
;MsgBox %FName%`n%FNameOrig%
If (File1 = File2)
FileDelete %FNameOrig%
Else
FileMove %FNameOrig%, %FName%, 1
}
RestoreOriginals(SrcDir) {
Loop %SrcDir%*.orig
{
;MsgBox %A_LoopFileLongPath%`n%NewName%
NewName := SubStr(A_LoopFileLongPath, 1, -5)
FileMove %A_LoopFileLongPath%, %NewName%, 1
}
while FileExist(SrcDir . "*.orig")
Sleep 10
}