tests/test-mq
author Matt Mackall <mpm@selenic.com>
Thu, 20 May 2010 12:15:44 -0500
changeset 11200 12e5149cafca
parent 11108 8d0cdeaa12f3
child 11208 2313dc4d9817
permissions -rwxr-xr-x
strip: improve full backup message

#!/bin/sh

source $TESTDIR/helpers.sh

checkundo()
{
    if [ -f .hg/store/undo ]; then
	echo ".hg/store/undo still exists after $1"
    fi
}

echo "[extensions]" >> $HGRCPATH
echo "mq=" >> $HGRCPATH

echo "[mq]" >> $HGRCPATH
echo "plain=true" >> $HGRCPATH

echo % help
hg help mq

hg init a
cd a
echo a > a
hg ci -Ama

hg clone . ../k

mkdir b
echo z > b/z
hg ci -Ama

echo % qinit

hg qinit

cd ..
hg init b

echo % -R qinit

hg -R b qinit

hg init c

echo % qinit -c

hg --cwd c qinit -c
hg -R c/.hg/patches st

echo '% qinit; qinit -c'
hg init d
cd d
hg qinit
hg qinit -c
# qinit -c should create both files if they don't exist
echo '  .hgignore:'
cat .hg/patches/.hgignore
echo '  series:'
cat .hg/patches/series
hg qinit -c 2>&1 | sed -e 's/repository.*already/repository already/'
cd ..

echo '% qinit; <stuff>; qinit -c'
hg init e
cd e
hg qnew A
checkundo qnew
echo foo > foo
hg add foo
hg qrefresh
hg qnew B
echo >> foo
hg qrefresh
echo status >> .hg/patches/.hgignore
echo bleh >> .hg/patches/.hgignore
hg qinit -c
hg -R .hg/patches status
# qinit -c shouldn't touch these files if they already exist
echo '  .hgignore:'
cat .hg/patches/.hgignore
echo '  series:'
cat .hg/patches/series
cd ..

echo '% init --mq without repo'
mkdir f
cd f
hg init --mq
cd ..

echo '% init --mq with repo path'
hg init g
hg init --mq g
test -d g/.hg/patches/.hg && echo "ok" || echo "failed"

echo '% init --mq with nonexistent directory'
hg init --mq nonexistentdir

echo '% init --mq with bundle (non "local")'
hg -R a bundle --all a.bundle >/dev/null
hg init --mq a.bundle

cd a

hg qnew -m 'foo bar' test.patch

echo % qrefresh

echo a >> a
hg qrefresh
sed -e "s/^\(diff -r \)\([a-f0-9]* \)/\1 x/" \
    -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \
    -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" .hg/patches/test.patch

echo % empty qrefresh

hg qrefresh -X a
echo 'revision:'
hg diff -r -2 -r -1
echo 'patch:'
cat .hg/patches/test.patch
echo 'working dir diff:'
hg diff --nodates -q
# restore things
hg qrefresh
checkundo qrefresh

echo % qpop

hg qpop
checkundo qpop

echo % qpush with dump of tag cache

# Dump the tag cache to ensure that it has exactly one head after qpush.
rm -f .hg/tags.cache
hg tags > /dev/null
echo ".hg/tags.cache (pre qpush):"
sed 's/ [0-9a-f]*//' .hg/tags.cache
hg qpush
hg tags > /dev/null
echo ".hg/tags.cache (post qpush):"
sed 's/ [0-9a-f]*//' .hg/tags.cache

checkundo qpush

cd ..

echo % pop/push outside repo

hg -R a qpop
hg -R a qpush

cd a
hg qnew test2.patch

echo % qrefresh in subdir

cd b
echo a > a
hg add a
hg qrefresh

echo % pop/push -a in subdir

hg qpop -a
hg --traceback qpush -a

# setting columns & interactive tests truncating (issue1912)
echo % qseries
COLUMNS=4 hg qseries --config ui.interactive=true
COLUMNS=20 hg qseries --config ui.interactive=true -vs
hg qpop
hg qseries -vs
hg sum | grep mq
hg qpush
hg sum | grep mq

echo % qapplied
hg qapplied

echo % qtop
hg qtop

echo % prev
hg qapp -1

echo % next
hg qunapp -1

hg qpop
echo % commit should fail
hg commit

echo % push should fail
hg push ../../k

echo % import should fail
hg st .
echo foo >> ../a
hg diff > ../../import.diff
hg revert --no-backup ../a
hg import ../../import.diff
hg st
echo % import --no-commit should succeed
hg import --no-commit ../../import.diff
hg st
hg revert --no-backup ../a

echo % qunapplied
hg qunapplied

echo % qpush/qpop with index
hg qnew test1b.patch
echo 1b > 1b
hg add 1b
hg qrefresh
hg qpush 2
hg qpop 0
hg qpush test.patch+1
hg qpush test.patch+2
hg qpop test2.patch-1
hg qpop test2.patch-2
hg qpush test1b.patch+1

echo % qpush --move
hg qpop -a
hg qpush --move test2.patch # move to front
hg qpush --move test1b.patch
hg qpush --move test.patch # noop move
hg qseries -v
hg qpop -a
hg qpush --move test.patch # cleaning up
hg qpush --move test1b.patch
hg qpush --move bogus # nonexistent patch
hg qpush --move test.patch # already applied
hg qpush

echo % pop, qapplied, qunapplied
hg qseries -v
echo % qapplied -1 test.patch
hg qapplied -1 test.patch
echo % qapplied -1 test1b.patch
hg qapplied -1 test1b.patch
echo % qapplied -1 test2.patch
hg qapplied -1 test2.patch
echo % qapplied -1
hg qapplied -1
echo % qapplied
hg qapplied
echo % qapplied test1b.patch
hg qapplied test1b.patch
echo % qunapplied -1
hg qunapplied -1
echo % qunapplied
hg qunapplied
echo % popping
hg qpop
echo % qunapplied -1
hg qunapplied -1
echo % qunapplied
hg qunapplied
echo % qunapplied test2.patch
hg qunapplied test2.patch
echo % qunapplied -1 test2.patch
hg qunapplied -1 test2.patch
echo % popping -a
hg qpop -a
echo % qapplied
hg qapplied
echo % qapplied -1
hg qapplied -1
hg qpush

echo % push should succeed
hg qpop -a
hg push ../../k

echo % qpush/qpop error codes
errorcode()
{
    hg "$@" && echo "  $@ succeeds" || echo "  $@ fails"
}

# we want to start with some patches applied
hg qpush -a
echo "  % pops all patches and succeeds"
errorcode qpop -a
echo "  % does nothing and succeeds"
errorcode qpop -a
echo "  % fails - nothing else to pop"
errorcode qpop
echo "  % pushes a patch and succeeds"
errorcode qpush
echo "  % pops a patch and succeeds"
errorcode qpop
echo "  % pushes up to test1b.patch and succeeds"
errorcode qpush test1b.patch
echo "  % does nothing and succeeds"
errorcode qpush test1b.patch
echo "  % does nothing and succeeds"
errorcode qpop test1b.patch
echo "  % fails - can't push to this patch"
errorcode qpush test.patch
echo "  % fails - can't pop to this patch"
errorcode qpop test2.patch
echo "  % pops up to test.patch and succeeds"
errorcode qpop test.patch
echo "  % pushes all patches and succeeds"
errorcode qpush -a
echo "  % does nothing and succeeds"
errorcode qpush -a
echo "  % fails - nothing else to push"
errorcode qpush
echo "  % does nothing and succeeds"
errorcode qpush test2.patch


echo % strip
cd ../../b
echo x>x
hg ci -Ama
hg strip tip | hidebackup
hg unbundle .hg/strip-backup/*

echo % strip with local changes, should complain
hg up
echo y>y
hg add y
hg strip tip | hidebackup
echo % --force strip with local changes
hg strip -f tip | hidebackup

echo '% cd b; hg qrefresh'
hg init refresh
cd refresh
echo a > a
hg ci -Ama
hg qnew -mfoo foo
echo a >> a
hg qrefresh
mkdir b
cd b
echo f > f
hg add f
hg qrefresh
sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \
    -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" ../.hg/patches/foo
echo % hg qrefresh .
hg qrefresh .
sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \
    -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" ../.hg/patches/foo
hg status

echo % qpush failure
cd ..
hg qrefresh
hg qnew -mbar bar
echo foo > foo
echo bar > bar
hg add foo bar
hg qrefresh
hg qpop -a
echo bar > foo
hg qpush -a
hg st

echo % mq tags
hg log --template '{rev} {tags}\n' -r qparent:qtip

echo % bad node in status
hg qpop
hg strip -qn tip
hg tip 2>&1 | sed -e 's/unknown node .*/unknown node/'
hg branches 2>&1 | sed -e 's/unknown node .*/unknown node/'
hg qpop 2>&1 | sed -e 's/unknown node .*/unknown node/'

cat >>$HGRCPATH <<EOF
[diff]
git = True
EOF
cd ..
hg init git
cd git
hg qinit

hg qnew -m'new file' new
echo foo > new
chmod +x new
hg add new
hg qrefresh
sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \
    -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" .hg/patches/new

hg qnew -m'copy file' copy
hg cp new copy
hg qrefresh
sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \
    -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" .hg/patches/copy

hg qpop
hg qpush
hg qdiff
cat >>$HGRCPATH <<EOF
[diff]
git = False
EOF
hg qdiff --git
cd ..

echo % test file addition in slow path
hg init slow
cd slow
hg qinit
echo foo > foo
hg add foo
hg ci -m 'add foo'
hg qnew bar
echo bar > bar
hg add bar
hg mv foo baz
hg qrefresh --git
hg up -C 0
echo >> foo
hg ci -m 'change foo'
hg up -C 1
hg qrefresh --git 2>&1 | grep -v 'saving bundle'
cat .hg/patches/bar
hg log -v --template '{rev} {file_copies}\n' -r .
hg qrefresh --git
cat .hg/patches/bar
hg log -v --template '{rev} {file_copies}\n' -r .
hg qrefresh
grep 'diff --git' .hg/patches/bar

echo % test file move chains in the slow path
hg up -C 1
echo >> foo
hg ci -m 'change foo again'
hg up -C 2
hg mv bar quux
hg mv baz bleh
hg qrefresh --git 2>&1 | grep -v 'saving bundle'
cat .hg/patches/bar
hg log -v --template '{rev} {file_copies}\n' -r .
hg mv quux fred
hg mv bleh barney
hg qrefresh --git
cat .hg/patches/bar
hg log -v --template '{rev} {file_copies}\n' -r .

echo % refresh omitting an added file
hg qnew baz
echo newfile > newfile
hg add newfile
hg qrefresh
hg st -A newfile
hg qrefresh -X newfile
hg st -A newfile
hg revert newfile
rm newfile
hg qpop
hg qdel baz

echo % create a git patch
echo a > alexander
hg add alexander
hg qnew -f --git addalexander
grep diff .hg/patches/addalexander

echo % create a git binary patch
cat > writebin.py <<EOF
import sys
path = sys.argv[1]
open(path, 'wb').write('BIN\x00ARY')
EOF
python writebin.py bucephalus

python "$TESTDIR/md5sum.py" bucephalus
hg add bucephalus
hg qnew -f --git addbucephalus
grep diff .hg/patches/addbucephalus

echo % check binary patches can be popped and pushed
hg qpop
test -f bucephalus && echo % bucephalus should not be there
hg qpush
test -f bucephalus || echo % bucephalus should be there
python "$TESTDIR/md5sum.py" bucephalus


echo '% strip again'
cd ..
hg init strip
cd strip
touch foo
hg add foo
hg ci -m 'add foo'
echo >> foo
hg ci -m 'change foo 1'
hg up -C 0
echo 1 >> foo
hg ci -m 'change foo 2'
HGMERGE=true hg merge
hg ci -m merge
hg log
hg strip 1 | hidebackup
checkundo strip
hg log
cd ..

echo '% qclone'
qlog()
{
    echo 'main repo:'
    hg log --template '    rev {rev}: {desc}\n'
    echo 'patch repo:'
    hg -R .hg/patches log --template '    rev {rev}: {desc}\n'
}
hg init qclonesource
cd qclonesource
echo foo > foo
hg add foo
hg ci -m 'add foo'
hg qinit
hg qnew patch1
echo bar >> foo
hg qrefresh -m 'change foo'
cd ..

# repo with unversioned patch dir
hg qclone qclonesource failure

cd qclonesource
hg qinit -c
hg qci -m checkpoint
qlog
cd ..

# repo with patches applied
hg qclone qclonesource qclonedest
cd qclonedest
qlog
cd ..

# repo with patches unapplied
cd qclonesource
hg qpop -a
qlog
cd ..
hg qclone qclonesource qclonedest2
cd qclonedest2
qlog
cd ..

echo % 'test applying on an empty file (issue 1033)'
hg init empty
cd empty
touch a
hg ci -Am addempty
echo a > a
hg qnew -f -e changea
hg qpop
hg qpush
cd ..

echo % test qpush with --force, issue1087
hg init forcepush
cd forcepush
echo hello > hello.txt
echo bye > bye.txt
hg ci -Ama
hg qnew -d '0 0' empty
hg qpop
echo world >> hello.txt

echo % qpush should fail, local changes
hg qpush

echo % apply force, should not discard changes with empty patch
hg qpush -f 2>&1 | sed 's,^.*/patch,patch,g'
hg diff --config diff.nodates=True
hg qdiff --config diff.nodates=True
hg log -l1 -p
hg qref -d '0 0'
hg qpop
echo universe >> hello.txt
echo universe >> bye.txt

echo % qpush should fail, local changes
hg qpush

echo % apply force, should discard changes in hello, but not bye
hg qpush -f
hg st
hg diff --config diff.nodates=True
hg qdiff --config diff.nodates=True

echo % test popping revisions not in working dir ancestry
hg qseries -v
hg up qparent
hg qpop

cd ..
hg init deletion-order
cd deletion-order

touch a
hg ci -Aqm0

hg qnew rename-dir
hg rm a
hg qrefresh

mkdir a b
touch a/a b/b
hg add -q a b
hg qrefresh

echo % test popping must remove files added in subdirectories first
hg qpop
cd ..