# HG changeset patch # User Vadim Gelfer # Date 1147710447 25200 # Node ID 1cad19678b4cb5a20c3172a3f960366ae8d969cb # Parent dfa17bd1d45ed4f46c50a4fdfd3dd29721bdb22f# Parent 6563438219e3710d2ae8bd84fca69c1080e5dbce merge with crew. diff --git a/doc/hgrc.5.txt b/doc/hgrc.5.txt --- a/doc/hgrc.5.txt +++ b/doc/hgrc.5.txt @@ -234,10 +234,9 @@ hooks:: is in $HG_PARENT2. If update succeeded, $HG_ERROR=0. If update failed (e.g. because conflicts not resolved), $HG_ERROR=1. - In earlier releases, the names of hook environment variables did not - have a "HG_" prefix. These unprefixed names are still provided in - the environment for backwards compatibility, but their use is - deprecated, and they will be removed in a future release. + Note: In earlier releases, the names of hook environment variables + did not have a "HG_" prefix. The old unprefixed names are no longer + provided in the environment. The syntax for Python hooks is as follows: diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -797,7 +797,7 @@ def backout(ui, repo, rev, **opts): (nice(repo.changelog.tip()), nice(node))) if opts['merge'] and op1 != node: ui.status(_('merging with changeset %s\n') % nice(op1)) - update(ui, repo, hex(op1), **opts) + doupdate(ui, repo, hex(op1), **opts) def bundle(ui, repo, fname, dest="default-push", **opts): """create a changegroup file @@ -947,7 +947,7 @@ def clone(ui, source, dest=None, **opts) f.close() if not opts['noupdate']: - update(repo.ui, repo) + doupdate(repo.ui, repo) d.close() @@ -1305,10 +1305,11 @@ def debugindexdot(ui, file_): r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_, "", 0) ui.write("digraph G {\n") for i in range(r.count()): - e = r.index[i] - ui.write("\t%d -> %d\n" % (r.rev(e[4]), i)) - if e[5] != nullid: - ui.write("\t%d -> %d\n" % (r.rev(e[5]), i)) + node = r.node(i) + pp = r.parents(node) + ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i)) + if pp[1] != nullid: + ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i)) ui.write("}\n") def debugrename(ui, repo, file, rev=None): @@ -1956,7 +1957,7 @@ def merge(ui, repo, node=None, **opts): marked as changed for the next commit and a commit must be performed before any further updates are allowed. """ - return update(ui, repo, node=node, merge=True, **opts) + return doupdate(ui, repo, node=node, merge=True, **opts) def outgoing(ui, repo, dest="default-push", **opts): """show changesets not found in destination @@ -2035,7 +2036,7 @@ def postincoming(ui, repo, modheads, opt return if optupdate: if modheads == 1: - return update(ui, repo) + return doupdate(ui, repo) else: ui.status(_("not updating, since new heads added\n")) if modheads > 1: @@ -2740,15 +2741,19 @@ def update(ui, repo, node=None, merge=Fa there is a linear relationship between the current version and the requested version, the result is the requested version. - Otherwise the result is a merge between the contents of the - current working directory and the requested version. Files that - changed between either parent are marked as changed for the next - commit and a commit must be performed before any further updates - are allowed. + To merge the working directory with another revision, use the + merge command. By default, update will refuse to run if doing so would require merging or discarding local changes. """ + if merge: + ui.warn(_('(the -m/--merge option is deprecated; ' + 'use the merge command instead)\n')) + return doupdate(ui, repo, node, merge, clean, force, branch, **opts) + +def doupdate(ui, repo, node=None, merge=False, clean=False, force=None, + branch=None, **opts): if branch: br = repo.branchlookup(branch=branch) found = [] @@ -3115,7 +3120,7 @@ table = { "^update|up|checkout|co": (update, [('b', 'branch', '', _('checkout the head of a specific branch')), - ('m', 'merge', None, _('allow merging of branches')), + ('m', 'merge', None, _('allow merging of branches (DEPRECATED)')), ('C', 'clean', None, _('overwrite locally modified files')), ('f', 'force', None, _('force a merge with outstanding changes'))], _('hg update [-b TAG] [-m] [-C] [-f] [REV]')), diff --git a/mercurial/httprepo.py b/mercurial/httprepo.py --- a/mercurial/httprepo.py +++ b/mercurial/httprepo.py @@ -11,6 +11,25 @@ from i18n import gettext as _ from demandload import * demandload(globals(), "hg os urllib urllib2 urlparse zlib util httplib") +class passwordmgr(urllib2.HTTPPasswordMgr): + def __init__(self, ui): + urllib2.HTTPPasswordMgr.__init__(self) + self.ui = ui + + def find_user_password(self, realm, authuri): + authinfo = urllib2.HTTPPasswordMgr.find_user_password( + self, realm, authuri) + if authinfo != (None, None): + return authinfo + + self.ui.write(_("http authorization required\n")) + self.ui.status(_("realm: %s\n") % realm) + user = self.ui.prompt(_("user:"), default=None) + passwd = self.ui.getpass() + + self.add_password(realm, authuri, user, passwd) + return (user, passwd) + class httprepository(remoterepository): def __init__(self, ui, path): # fix missing / after hostname @@ -53,13 +72,21 @@ class httprepository(remoterepository): if host and not no_proxy: proxy_handler = urllib2.ProxyHandler({"http" : "http://" + host}) - authinfo = None + proxyauthinfo = None if user and passwd: passmgr = urllib2.HTTPPasswordMgrWithDefaultRealm() passmgr.add_password(None, host, user, passwd) - authinfo = urllib2.ProxyBasicAuthHandler(passmgr) + proxyauthinfo = urllib2.ProxyBasicAuthHandler(passmgr) - opener = urllib2.build_opener(proxy_handler, authinfo) + if ui.interactive: + passmgr = passwordmgr(ui) + opener = urllib2.build_opener( + proxy_handler, proxyauthinfo, + urllib2.HTTPBasicAuthHandler(passmgr), + urllib2.HTTPDigestAuthHandler(passmgr)) + else: + opener = urllib2.build_opener(proxy_handler, proxyauthinfo) + # 1.0 here is the _protocol_ version opener.addheaders = [('User-agent', 'mercurial/proto-1.0')] urllib2.install_opener(opener) diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -136,8 +136,7 @@ class localrepository(object): def runhook(name, cmd): self.ui.note(_("running hook %s: %s\n") % (name, cmd)) - env = dict([('HG_' + k.upper(), v) for k, v in args.iteritems()] + - [(k.upper(), v) for k, v in args.iteritems()]) + env = dict([('HG_' + k.upper(), v) for k, v in args.iteritems()]) r = util.system(cmd, environ=env, cwd=self.root) if r: desc, r = util.explain_exit(r) diff --git a/mercurial/ui.py b/mercurial/ui.py --- a/mercurial/ui.py +++ b/mercurial/ui.py @@ -8,7 +8,7 @@ import ConfigParser from i18n import gettext as _ from demandload import * -demandload(globals(), "errno os re smtplib socket sys tempfile util") +demandload(globals(), "errno getpass os re smtplib socket sys tempfile util") class ui(object): def __init__(self, verbose=False, debug=False, quiet=False, @@ -224,15 +224,18 @@ class ui(object): def readline(self): return sys.stdin.readline()[:-1] - def prompt(self, msg, pat, default="y"): + def prompt(self, msg, pat=None, default="y"): if not self.interactive: return default while 1: self.write(msg, " ") r = self.readline() - if re.match(pat, r): + if not pat or re.match(pat, r): return r else: self.write(_("unrecognized response\n")) + def getpass(self, prompt=None, default=None): + if not self.interactive: return default + return getpass.getpass(prompt or _('password: ')) def status(self, *msg): if not self.quiet: self.write(*msg) def warn(self, *msg): @@ -268,8 +271,10 @@ class ui(object): def sendmail(self): s = smtplib.SMTP() - s.connect(host = self.config('smtp', 'host', 'mail'), - port = int(self.config('smtp', 'port', 25))) + mailhost = self.config('smtp', 'host') + if not mailhost: + raise util.Abort(_('no [smtp]host in hgrc - cannot send mail')) + s.connect(host=mailhost, port=int(self.config('smtp', 'port', 25))) if self.configbool('smtp', 'tls'): s.ehlo() s.starttls() diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -536,12 +536,16 @@ if os.name == 'nt': def os_rcpath(): '''return default os-specific hgrc search path''' path = system_rcpath() - path.append(os.path.join(os.path.expanduser('~'), 'mercurial.ini')) + path.append(user_rcpath()) userprofile = os.environ.get('USERPROFILE') if userprofile: path.append(os.path.join(userprofile, 'mercurial.ini')) return path + def user_rcpath(): + '''return os-specific hgrc search path to the user dir''' + return os.path.join(os.path.expanduser('~'), 'mercurial.ini') + def parse_patch_output(output_line): """parses the output produced by patch and returns the file name""" pf = output_line[14:] diff --git a/mercurial/util_win32.py b/mercurial/util_win32.py --- a/mercurial/util_win32.py +++ b/mercurial/util_win32.py @@ -16,7 +16,7 @@ import win32api from demandload import * from i18n import gettext as _ demandload(globals(), 'errno os pywintypes win32con win32file win32process') -demandload(globals(), 'cStringIO winerror') +demandload(globals(), 'cStringIO win32com.shell:shell,shellcon winerror') class WinError: winerror_map = { @@ -180,9 +180,24 @@ def testpid(pid): def system_rcpath_win32(): '''return default os-specific hgrc search path''' proc = win32api.GetCurrentProcess() - filename = win32process.GetModuleFileNameEx(proc, 0) + try: + # This will fail on windows < NT + filename = win32process.GetModuleFileNameEx(proc, 0) + except: + filename = win32api.GetModuleFileName(0) return [os.path.join(os.path.dirname(filename), 'mercurial.ini')] +def user_rcpath(): + '''return os-specific hgrc search path to the user dir''' + userdir = os.path.expanduser('~') + if userdir == '~': + # We are on win < nt: fetch the APPDATA directory location and use + # the parent directory as the user home dir. + appdir = shell.SHGetPathFromIDList( + qshell.SHGetSpecialFolderLocation(0, shellcon.CSIDL_APPDATA)) + userdir = os.path.dirname(appdir) + return os.path.join(userdir, 'mercurial.ini') + class posixfile_nt(object): '''file object with posix-like semantics. on windows, normal files can not be deleted or renamed if they are open. must open diff --git a/tests/README b/tests/README --- a/tests/README +++ b/tests/README @@ -16,10 +16,10 @@ test-.err. There are some tricky points here that you should be aware of when writing tests: -- hg commit and hg up -m want user interaction +- hg commit and hg merge want user interaction for commit use -m "text" - for hg up -m, set HGMERGE to something noninteractive (like true or merge) + for hg merge, set HGMERGE to something noninteractive (like true or merge) - changeset hashes will change based on user and date which make things like hg history output change diff --git a/tests/test-conflict b/tests/test-conflict --- a/tests/test-conflict +++ b/tests/test-conflict @@ -10,7 +10,7 @@ hg co 0 echo "something else" > a hg commit -m branch2 -d "1000000 0" HGMERGE=merge; export HGMERGE -hg up -m 1 +hg merge 1 hg id egrep -v ">>>|<<<" a hg status diff --git a/tests/test-confused-revert b/tests/test-confused-revert --- a/tests/test-confused-revert +++ b/tests/test-confused-revert @@ -28,7 +28,7 @@ hg co -C 0 echo foo-b > a hg commit -m "2b" -d "1000000 0" -HGMERGE=true hg update -m 1 +HGMERGE=true hg merge 1 echo "%%% should show foo-b" cat a diff --git a/tests/test-excessive-merge b/tests/test-excessive-merge --- a/tests/test-excessive-merge +++ b/tests/test-excessive-merge @@ -17,12 +17,12 @@ hg co 0 echo blah > b hg ci -m "branch b" -d "1000000 0" -HGMERGE=true hg up -m 1 +HGMERGE=true hg merge 1 hg ci -m "merge b/a -> blah" -d "1000000 0" hg co 1 -HGMERGE=true hg up -m 2 +HGMERGE=true hg merge 2 hg ci -m "merge a/b -> blah" -d "1000000 0" hg log @@ -43,4 +43,4 @@ echo hg debugindex .hg/data/a.i -hg verify \ No newline at end of file +hg verify diff --git a/tests/test-filebranch b/tests/test-filebranch --- a/tests/test-filebranch +++ b/tests/test-filebranch @@ -41,7 +41,7 @@ hg debugstate | cut -b 1-16,35- echo merging hg pull ../a -env HGMERGE=../merge hg update -vm +env HGMERGE=../merge hg merge -v echo 2m > foo echo 2b > baz diff --git a/tests/test-flags b/tests/test-flags --- a/tests/test-flags +++ b/tests/test-flags @@ -27,7 +27,7 @@ hg pull ../test2 hg heads hg history -hg -v co -m +hg -v merge ls -l ../test[12]/a > foo cut -b 1-10 < foo diff --git a/tests/test-hook b/tests/test-hook --- a/tests/test-hook +++ b/tests/test-hook @@ -29,7 +29,7 @@ hg update -C 0 echo b > b hg add b hg commit -m b -d '1 0' -hg update -m 1 +hg merge 1 hg commit -m merge -d '2 0' cd ../b diff --git a/tests/test-merge1 b/tests/test-merge1 --- a/tests/test-merge1 +++ b/tests/test-merge1 @@ -22,7 +22,7 @@ hg add c hg commit -m "commit #2" -d "1000000 0" echo This is file b1 > b echo %% no merges expected -env HGMERGE=../merge hg update -m 1 +env HGMERGE=../merge hg merge 1 cd ..; /bin/rm -rf t mkdir t @@ -41,9 +41,9 @@ hg add c hg commit -m "commit #2" -d "1000000 0" echo This is file b2 > b echo %% merge should fail -env HGMERGE=../merge hg update -m 1 +env HGMERGE=../merge hg merge 1 echo %% merge of b expected -env HGMERGE=../merge hg update -f -m 1 +env HGMERGE=../merge hg merge -f 1 cd ..; /bin/rm -rf t echo %% @@ -68,9 +68,9 @@ cat b echo This is file b22 > b echo %% merge fails -env HGMERGE=../merge hg update -m 2 +env HGMERGE=../merge hg merge 2 echo %% merge expected! -env HGMERGE=../merge hg update -f -m 2 +env HGMERGE=../merge hg merge -f 2 cd ..; /bin/rm -rf t mkdir t @@ -90,7 +90,7 @@ hg add c hg commit -m "commit #3" -d "1000000 0" echo This is file b33 > b echo %% merge of b should fail -env HGMERGE=../merge hg update -m 2 +env HGMERGE=../merge hg merge 2 echo %% merge of b expected -env HGMERGE=../merge hg update -f -m 2 +env HGMERGE=../merge hg merge -f 2 cd ..; /bin/rm -rf t diff --git a/tests/test-merge4 b/tests/test-merge4 --- a/tests/test-merge4 +++ b/tests/test-merge4 @@ -11,7 +11,7 @@ hg update 0 echo This is file c1 > c hg add c hg commit -m "commit #2" -d "1000000 0" -hg update -m 1 +hg merge 1 rm b echo This is file c22 > c hg commit -m "commit #3" -d "1000000 0" diff --git a/tests/test-merge6 b/tests/test-merge6 --- a/tests/test-merge6 +++ b/tests/test-merge6 @@ -33,14 +33,14 @@ hg clone B1 B2 cd A1 hg pull ../B1 -hg update -m +hg merge hg commit -m "commit test" -d "1000000 0" echo bar should remain deleted. hg manifest cd ../B2 hg pull ../A2 -hg update -m +hg merge hg commit -m "commit test" -d "1000000 0" echo bar should remain deleted. hg manifest diff --git a/tests/test-merge7 b/tests/test-merge7 --- a/tests/test-merge7 +++ b/tests/test-merge7 @@ -35,7 +35,7 @@ hg commit -m "2 -> 2.5" -d "1000000 0" # now pull and merge from test-a hg pull ../test-a -HGMERGE=merge hg update -m +HGMERGE=merge hg merge # resolve conflict cat >test.txt <<"EOF" one @@ -57,7 +57,7 @@ hg commit -m "two -> two-point-one" -d " # pull and merge from test-a again cd ../test-b hg pull ../test-a -HGMERGE=merge hg update --debug -m +HGMERGE=merge hg merge --debug cat test.txt | sed "s% .*%%" diff --git a/tests/test-merge7.out b/tests/test-merge7.out --- a/tests/test-merge7.out +++ b/tests/test-merge7.out @@ -22,7 +22,7 @@ added 1 changesets with 1 changes to 1 f (run 'hg heads' to see heads, 'hg merge' to merge) merge: warning: conflicts during merge resolving manifests - force None allow 1 moddirstate True linear False + force False allow True moddirstate True linear False ancestor 055d847dd401 local 2eded9ab0a5c remote 84cf5750dd20 test.txt versions differ, resolve merging test.txt diff --git a/tests/test-push-warn b/tests/test-push-warn --- a/tests/test-push-warn +++ b/tests/test-push-warn @@ -23,7 +23,7 @@ hg commit -m "3" -d "1000000 0" hg push ../a hg pull ../a hg push ../a -hg up -m +hg merge hg commit -m "4" -d "1000000 0" hg push ../a cd .. @@ -44,7 +44,7 @@ for i in 0 1; do hg ci -m d-$i -d "1000000 0" done -HGMERGE=true hg co -m 3 +HGMERGE=true hg merge 3 hg ci -m c-d -d "1000000 0" hg push ../c diff --git a/tests/test-ro-message b/tests/test-ro-message --- a/tests/test-ro-message +++ b/tests/test-ro-message @@ -14,4 +14,4 @@ echo 'stationary' >>b/vehicle "$HG" commit -m 'Clarifying the vehicle.' "$HG" update -C 1 chmod a-w b/vehicle -"$HG" update -m 2 2>&1 | sed 's|^\(.*[ ]\).*/\([^/]*/[^/]*/[^/]*\)$|\1\2|g' +"$HG" merge 2 2>&1 | sed 's|^\(.*[ ]\).*/\([^/]*/[^/]*/[^/]*\)$|\1\2|g' diff --git a/tests/test-tags b/tests/test-tags --- a/tests/test-tags +++ b/tests/test-tags @@ -27,7 +27,7 @@ echo 1 > b hg add b hg commit -m "branch" -d "1000000 0" hg id -hg co -m 1 +hg merge 1 hg id hg status diff --git a/tests/test-up-local-change b/tests/test-up-local-change --- a/tests/test-up-local-change +++ b/tests/test-up-local-change @@ -29,7 +29,7 @@ hg --debug up hg parents hg --debug up 0 hg parents -hg --debug up -m || echo failed +hg --debug merge || echo failed hg parents hg --debug up hg parents @@ -50,8 +50,8 @@ hg -q pull ../r1 hg status hg parents hg --debug up || echo failed -hg --debug up -m || echo failed -hg --debug up -f -m +hg --debug merge || echo failed +hg --debug merge -f hg parents hg diff | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" diff --git a/tests/test-up-local-change.out b/tests/test-up-local-change.out --- a/tests/test-up-local-change.out +++ b/tests/test-up-local-change.out @@ -112,7 +112,7 @@ failed abort: outstanding uncommitted changes failed resolving manifests - force None allow 1 moddirstate True linear False + force False allow True moddirstate True linear False ancestor a0c8bcbbb45c local 1165e8bd193e remote 4096f2872392 a versions differ, resolve b versions differ, resolve