Automatically close merged branches in mercurial

@echo off

:: :: ::
:: This script can be run by hand or added as a hook to mercurial (.hg/hgrc):
::      [hooks]
::      changegroup.closemerged = c:\scriptdirectory\closemerged.bat PROD c:\repo\projectdirectory
:: :: ::
:: Usage:
::  closemerged.bat MAINBRANCH PROJECTDIRECTORY
:: :: ::

set MAIN=%1

cd %2

echo Searching for not closed branches that were merged to %MAIN%...
hg log -r "head()-closed()-branch(%MAIN%)-branch(TEST)" --template "{branch}," > tmpFile
set /p BRANCHES=<tmpFile
del tmpFile

echo Processing branches: %BRANCHES%
call :parse "%BRANCHES%"
goto :end


:parse
setlocal
set list=%1
set list=%list:"=%
FOR /f "tokens=1* delims=," %%a IN ("%list%") DO (
  if not "%%a" == "" call :sub %%a
  if not "%%b" == "" call :parse "%%b"
)
endlocal
exit /b

:sub
setlocal
echo Querying %1
:: get last revision of branch
hg log -r "%1" --template {node} > tmpFileB1
:: get revision of ancestor of main branch and queried branch
hg log -r "ancestor('%MAIN%','%1')" --template {node} > tmpFileB2
set /p b1=<tmpFileB1
set /p b2=<tmpFileB2
del tmpFileB1
del tmpFileB2
:: if revision nodes are the same it means that branches are merged
if "%b1%"=="%b2%" call :close %1
endlocal
exit /b

:close
setlocal
echo Closing %1
hg update --clean %1
hg ci --close-branch -m "Closing merged branch."
endlocal
exit /b

:end
echo Updating to %MAIN% branch
hg update --clean %MAIN%

Mercurial log with one-liners

hg log --template '{node|short} | {date|isodatesec} | {author|user}@{branch}: {desc|strip|firstline}\n'

Once you have a nice template for one-line summaries of changesets, you can add a command alias in your ~/.hgrc file like this:

[alias]
shortlog = log --template '{node|short} | {date|isodatesec} | {author|user}@{branch}: {desc|strip|firstline}\n'

With the alias installed you can now type hg shortlog.

via Mercurial log with one-liners

Mercurial hooks

Useful Mercurial Hooks

Add/document commit-hook

To close the branch retroactively, just update to it and close it. You can also do so in bulk if you need to:

for b in `hg heads --template '{branches}\n'`; do \
    tip=`hg log -r $b --template '{node}'`; \
    anc=`hg debuganc $b default | cut -d: -f2`; \
    if [ $tip = $anc ]; then \
      echo $b merged; \
      hg up $b; \
      hg ci --close-branch -m 'Closing merged branch.'; \
    else \
      echo $b unmerged; \
    fi; \
  done

via Using a named branch

hg log -r 'head()-parents(merge())-closed()' --template '{branch}\n'

via hg hook to detect unmerged changesets

Three-way merge for hg using vim

I accidentally blew away my .hgrc and it took me some time to recover my 3-way merge inspired by Dan McGee’s article on the subject. So for my and your future reference here’s what you need in your .hgrc to get hg merge to give you a three merge window in vim:

[ui]
merge = vimdiff

[merge-tools]
vimdiff.executable = vim
vimdiff.args = -f -d -c "wincmd J" "$output" "$local" "$base" "$other"