Mercurial hg(v4) get trunk commits since given revision - mercurial

The screenshot shows that hg(v2) can get trunk only commits since a particular revision. In the example below, rev 1 is not a trunk commit.
How do we get trunk only commits since given rev in hg v4?
To create the hg test repository used here, run the following:
$ mkdir hg-multi-branch
$ cd hg-multi-branch
$ hg init
$ v=A && touch $v && hg add $v && hg commit -m "Added $v"
$ hg branch feature
$ v=B && touch $v && hg add $v && hg commit -m "Added $v"
$ hg co default
$ v=C && touch $v && hg add $v && hg commit -m "Added $v"
One could use the -b default opt to get commits from the default branch. However using -b is not exactly the same as --follow-parent. There are cases where the output would be different.

as #Lazy-Badger said :: range should work for you
hg log --follow-first -r 0::tip
all changesets that are descendants of x and ancestors of y, including x and y themselves.
https://www.mercurial-scm.org/repo/hg/help/revsets

Related

Create a Mercurial alias that runs two commands and takes one paramater

I'm trying to create an alias and allows me to commit my changes and push all changesets for the current branch.
I'm running this from a Windows command prompt.
I've read this question and this question and so far have this:
ci-push = !hg ci -m $1 && hg push -b .
When I try this i get the error:
abort: Commit: The system cannot find the file specified
If I try:
ci-push = !hg ci -m %1 && hg push -b .
then it appears to work (prompts for auth and pushes the commit), but my commit message is:
%1
Is this even possible from a Windows cmd prompt?
On Windows, %USERPROFILE%\mercurial.ini:
[alias]
ll = log -l$1
Testing:
>hg ll
abort: too few arguments for command alias
> hg ll 5
changeset:...
Shell alias (%USERPROFILE%\mercurial.ini):
[alias]
ld = !hg log -r $1 && hg diff -r $1
Testing:
>hg ld 154
changeset: 154:5bb3aba44eab
....
diff -r 5bb3aba44eab ....
P.S.
When using $N with spaces you should use quotes (!hg ci -m "$1" ... in aliases).

Mercurial: move MQ patch to shelve?

Emacs VC mode show changes in directory state but ignore MQ changes...
I want to remove patch from queue and apply it on working directory.
This is possible with usual patch command, but it require passing some arguments and paths to utilities (which is inconvenient as not all environment allow autocompletion).
I expect hg built-in solution. Ideally - to move patch to shelve.
Moving changes from MQ to working tree and forgetting it:
$ hg qgoto my.patch
$ hg qpop
$ hg qdel --keep my.patch
$ patch -p1 .hg/patches/my.patch
$ rm .hg/patches/my.patch
In Emacs to see difference in top MQ patches I find command C-u C-x v D qparent RET qtip RET which is:
$ hg diff -r qparent:qtip
or shorter:
$ hg diff -r qparent
or:
$ hg qdiff
but latest command doesn't present in Emacs VC mode.

Is there a way to push all bookmarks to another repo, all at once? (Mercurial)

I am importing one Mercurial repo into another, maintaining history. There are several bookmarked heads on the default branch, and I want those bookmarked heads to still be bookmarked in the new, merged repo. As far as I can tell, the two ways to do this is to either,
pull each bookmark individually
pull the entire thing and recreate the bookmarks by hand.
Extending the previous answer, here's how to push all branches using awk and the output of hg bookmarks in bash:
hg bookmarks | awk '{if (NF == 3) print $2; else print $1;}' | xargs -n 1 hg push -f -B
Unix:
hg push $(hg bookmarks -T "-B {bookmark} ")
Windows:
for /f "delims=" %A in ('hg bookmarks -T "-B {bookmark} "') do #hg push %A
PowerShell:
hg bookmarks -T "{bookmark}\n" | %{ Write-Host === Bookmark $_ === ; hg push -B $_ }
-B parameter can be used in push any amount of times. Full bookmarks list for repo you can get from hg bookmarks

Tortoise HG - Add a tag on commit

At the moment, I only know how to add a tag after a commit. This means that a get a second commit that just contains the tag. Is it possible to add a tag on commit?
No, because a tag is an entry in the .hgtags file at the root of your repository containing the changeset id and the tag name, and this file itself is under revision control. The changeset id isn't known until the changeset is created, so tagging creates another changeset to check in the .hgtags file recording the tag for that changeset.
According to mercurial wiki, it is impossible. Just like Mark said.
https://www.mercurial-scm.org/wiki/Tag
But then, i just wondering. Why not mercurial ignoring the .hgtags file altogether ? just like it ignores .hg/ folder.
So mercurial won't include .hgtags everytime it's generating a changeset ID.
Would be great if .hgtags, .hgignores, etc is resides inside .hg/
For my point of view, Hg tagging system is a bit messy because creating a tag changes the history and needs merging and committing even if no project file has changed. Tagging can burden a history graph very quickly.
I was used of SVN tagging which was done on a separate branch, which has the advantage not to change working branch history. Moreover, tagging can be done from any branch, because Hg takes tags from the .hgtags files on the heads of all branches.
The little script below creates a branch "tagging" and puts tags in it. It merges the current branch in "tagging" branch, so it's easy to see the changeset tag was done from (it especially avoids long refreshes when switching branch).
It can probably be improved, but it suits my needs.
I strongly recommend making a clone of your project before testing this script, in case it does not behave as you expect!
#!/bin/bash
function echo_red()
{
echo -n -e "\e[01;31m"
echo -n "$1"
echo -e "\e[00m"
}
export -f echo_red
# Display the help and exit
function show_help {
echo "Usage: $0 [hg_tag_options ...]"
echo " tags a version (current if not specified) in the 'tagging' branch."
echo " Options are the 'hg tag' ones, plus"
echo " -?, -h, --help Show (this) help"
exit 1
}
# Parse the command-line arguments
function parse_args {
for arg in "${commandline_args[#]}"
do
case "$arg" in #(
'-?' | -h | --help )
show_help
;;
esac
done
}
commandline_args=("$#")
if [ "$commandline_args" = "" ]
then
show_help
fi
parse_args
VER=`hg id | sed 's#\([0-9a-z]*\).*#\1#g'`
BRANCH=`hg branch`
# Check for clean directory
TEST=`hg st -S -q`
if [ "$TEST" != "" ]
then
echo_red "Directory contains unresolved files !"
exit 1
fi
hg update --check >/dev/null
if [ $? -ne 0 ]
then
echo_red "Directory contains unresolved files !"
exit 1
fi
# Switch to tagging branch
hg update tagging >/dev/null
if [ $? -ne 0 ]
then
echo "Creating new 'tagging' branch."
hg update default >/dev/null
hg branch tagging
fi
# Merge if changes detected
TEST=`hg diff -r $VER -X .hgtags --stat`
if [ "$TEST" != "" ]
then
#take only the 'tagging' version of hgtags
cp .hgtags .hgtags.bak
hg merge -r $VER --tool internal:other >/dev/null
rm .hgtags
mv .hgtags.bak .hgtags
hg commit -m Merged
fi
# Tag and Switch back to original
hg tag -r $VER $#
hg update $BRANCH >/dev/null
hg update $VER >/dev/null
Example Usage:
hg_tag.sh [-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] test_v1_5
Not sure if this is what you are looking for, but you can move the tag to a different changeset.
hg com -m "moving tag to this changeset"
hg tag 0.1 -f
hg push

logging mercurial transactions

this is a small addition to the previous script, and this time I would like to log details for the backup.
script /tmp/commit-push-log
# add all files to the repository
for REPOSITORY in $#
do
cd $REPOSITORY
# commit the changes
hg commit -A -m "Commit changes `date`"
# push the changes to the remote repository
if hg push
then
logger hg push completed without failure
else
logger hg push fails
fi
done
exit
cat /tmp/commit-push-log | logger
rm /tmp/commit-push-log
the problem is that i don't see any mercurial messages in the log. What can go wrong in my script?
You should not use static tmp filenames. Use mktemp, it's far safer.
You should cd "$REPOSITORY" instead of "cd $REPOSITORY" or things will get funny when REPOSITORY will contain any spaces or special characters.
You should not write automated commit comments. See here for the great article on this topic.
hg probably outputs errors to stderr. Use hg commit -A -m "$comment" 2>&1 and hg push 2>&1
my current version
for REPOSITORY in $#
do
# new temp file
OUTPUT_LOG=`tempfile`
echo -n > $OUTPUT_LOG
# checks whether $REPO is a repo
if [ ! -d $REPOSITORY/.hg ]; then
echo "Not a repository: $REPOSITORY"
exit 1;
fi
# change to that dir
cd "$REPOSITORY"
logger "Repository: $REPOSITORY"
# commit the changes
hg commit -A -m "Commit changes `date`" 2>&1 >> $OUTPUT_LOG
# push the changes to the remote repository
if hg push 2>&1 >> $OUTPUT_LOG
then
logger hg push completed without failure
else
logger hg push fails
exit 1;
fi
# log the contents and delete the tempfile
cat $OUTPUT_LOG | logger
rm -f $OUTLOG_LOG
done
exit 0