##// END OF EJS Templates
misc: update year in copyright lines...
FUJIWARA Katsunori -
r30907:75149f84 stable
parent child Browse files
Show More
@@ -1,162 +1,162 b''
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2 <html>
2 <html>
3 <head>
3 <head>
4 <title>Mercurial for Windows</title>
4 <title>Mercurial for Windows</title>
5 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
5 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
6 <style type="text/css">
6 <style type="text/css">
7 <!--
7 <!--
8 html {
8 html {
9 font-family: sans-serif;
9 font-family: sans-serif;
10 margin: 1em 2em;
10 margin: 1em 2em;
11 }
11 }
12
12
13 p {
13 p {
14 margin-top: 0.5em;
14 margin-top: 0.5em;
15 margin-bottom: 0.5em;
15 margin-bottom: 0.5em;
16 }
16 }
17
17
18 pre {
18 pre {
19 margin: 0.25em 0em;
19 margin: 0.25em 0em;
20 padding: 0.5em;
20 padding: 0.5em;
21 background-color: #EEE;
21 background-color: #EEE;
22 border: thin solid #CCC;
22 border: thin solid #CCC;
23 }
23 }
24
24
25 .indented {
25 .indented {
26 padding-left: 10pt;
26 padding-left: 10pt;
27 }
27 }
28 -->
28 -->
29 </style>
29 </style>
30 </head>
30 </head>
31
31
32 <body>
32 <body>
33 <h1>Mercurial for Windows</h1>
33 <h1>Mercurial for Windows</h1>
34
34
35 <p>Welcome to Mercurial for Windows!</p>
35 <p>Welcome to Mercurial for Windows!</p>
36
36
37 <p>
37 <p>
38 Mercurial is a command-line application. You must run it from
38 Mercurial is a command-line application. You must run it from
39 the Windows command prompt (or if you're hard core, a <a
39 the Windows command prompt (or if you're hard core, a <a
40 href="http://www.mingw.org/">MinGW</a> shell).
40 href="http://www.mingw.org/">MinGW</a> shell).
41 </p>
41 </p>
42
42
43 <p class="indented">
43 <p class="indented">
44 <i>Note: the standard <a href="http://www.mingw.org/">MinGW</a>
44 <i>Note: the standard <a href="http://www.mingw.org/">MinGW</a>
45 msys startup script uses rxvt which has problems setting up
45 msys startup script uses rxvt which has problems setting up
46 standard input and output. Running bash directly works
46 standard input and output. Running bash directly works
47 correctly.</i>
47 correctly.</i>
48 </p>
48 </p>
49
49
50 <p>
50 <p>
51 For documentation, please visit the <a
51 For documentation, please visit the <a
52 href="https://mercurial-scm.org/">Mercurial web site</a>.
52 href="https://mercurial-scm.org/">Mercurial web site</a>.
53 You can also download a free book, <a
53 You can also download a free book, <a
54 href="http://hgbook.red-bean.com/">Mercurial: The Definitive
54 href="http://hgbook.red-bean.com/">Mercurial: The Definitive
55 Guide</a>.
55 Guide</a>.
56 </p>
56 </p>
57
57
58 <p>
58 <p>
59 By default, Mercurial installs to <tt>C:\Program
59 By default, Mercurial installs to <tt>C:\Program
60 Files\Mercurial</tt>. The Mercurial command is called
60 Files\Mercurial</tt>. The Mercurial command is called
61 <tt>hg.exe</tt>.
61 <tt>hg.exe</tt>.
62 </p>
62 </p>
63
63
64 <h1>Testing Mercurial after you've installed it</h1>
64 <h1>Testing Mercurial after you've installed it</h1>
65
65
66 <p>
66 <p>
67 The easiest way to check that Mercurial is installed properly is
67 The easiest way to check that Mercurial is installed properly is
68 to just type the following at the command prompt:
68 to just type the following at the command prompt:
69 </p>
69 </p>
70
70
71 <pre>
71 <pre>
72 hg
72 hg
73 </pre>
73 </pre>
74
74
75 <p>
75 <p>
76 This command should print a useful help message. If it does,
76 This command should print a useful help message. If it does,
77 other Mercurial commands should work fine for you.
77 other Mercurial commands should work fine for you.
78 </p>
78 </p>
79
79
80 <h1>Configuration notes</h1>
80 <h1>Configuration notes</h1>
81 <h4>Default editor</h4>
81 <h4>Default editor</h4>
82 <p>
82 <p>
83 The default editor for commit messages is 'notepad'. You can set
83 The default editor for commit messages is 'notepad'. You can set
84 the <tt>EDITOR</tt> (or <tt>HGEDITOR</tt>) environment variable
84 the <tt>EDITOR</tt> (or <tt>HGEDITOR</tt>) environment variable
85 to specify your preference or set it in <tt>mercurial.ini</tt>:
85 to specify your preference or set it in <tt>mercurial.ini</tt>:
86 </p>
86 </p>
87 <pre>
87 <pre>
88 [ui]
88 [ui]
89 editor = whatever
89 editor = whatever
90 </pre>
90 </pre>
91
91
92 <h4>Configuring a Merge program</h4>
92 <h4>Configuring a Merge program</h4>
93 <p>
93 <p>
94 It should be emphasized that Mercurial by itself doesn't attempt
94 It should be emphasized that Mercurial by itself doesn't attempt
95 to do a Merge at the file level, neither does it make any
95 to do a Merge at the file level, neither does it make any
96 attempt to Resolve the conflicts.
96 attempt to Resolve the conflicts.
97 </p>
97 </p>
98
98
99 <p>
99 <p>
100 By default, Mercurial will use the merge program defined by the
100 By default, Mercurial will use the merge program defined by the
101 <tt>HGMERGE</tt> environment variable, or uses the one defined
101 <tt>HGMERGE</tt> environment variable, or uses the one defined
102 in the <tt>mercurial.ini</tt> file. (see <a
102 in the <tt>mercurial.ini</tt> file. (see <a
103 href="https://mercurial-scm.org/wiki/MergeProgram">MergeProgram</a>
103 href="https://mercurial-scm.org/wiki/MergeProgram">MergeProgram</a>
104 on the Mercurial Wiki for more information)
104 on the Mercurial Wiki for more information)
105 </p>
105 </p>
106
106
107 <h1>Reporting problems</h1>
107 <h1>Reporting problems</h1>
108
108
109 <p>
109 <p>
110 Before you report any problems, please consult the <a
110 Before you report any problems, please consult the <a
111 href="https://mercurial-scm.org/">Mercurial web site</a>
111 href="https://mercurial-scm.org/">Mercurial web site</a>
112 and see if your question is already in our list of <a
112 and see if your question is already in our list of <a
113 href="https://mercurial-scm.org/wiki/FAQ">Frequently
113 href="https://mercurial-scm.org/wiki/FAQ">Frequently
114 Answered Questions</a> (the "FAQ").
114 Answered Questions</a> (the "FAQ").
115 </p>
115 </p>
116
116
117 <p>
117 <p>
118 If you cannot find an answer to your question, please feel free
118 If you cannot find an answer to your question, please feel free
119 to send mail to the Mercurial mailing list, at <a
119 to send mail to the Mercurial mailing list, at <a
120 href="mailto:mercurial@mercurial-scm.org">mercurial@mercurial-scm.org</a>.
120 href="mailto:mercurial@mercurial-scm.org">mercurial@mercurial-scm.org</a>.
121 <b>Remember</b>, the more useful information you include in your
121 <b>Remember</b>, the more useful information you include in your
122 report, the easier it will be for us to help you!
122 report, the easier it will be for us to help you!
123 </p>
123 </p>
124
124
125 <p>
125 <p>
126 If you are IRC-savvy, that's usually the fastest way to get
126 If you are IRC-savvy, that's usually the fastest way to get
127 help. Go to <tt>#mercurial</tt> on <tt>irc.freenode.net</tt>.
127 help. Go to <tt>#mercurial</tt> on <tt>irc.freenode.net</tt>.
128 </p>
128 </p>
129
129
130 <h1>Author and copyright information</h1>
130 <h1>Author and copyright information</h1>
131
131
132 <p>
132 <p>
133 Mercurial was written by <a href="http://www.selenic.com">Matt
133 Mercurial was written by <a href="http://www.selenic.com">Matt
134 Mackall</a>, and is maintained by Matt and a team of volunteers.
134 Mackall</a>, and is maintained by Matt and a team of volunteers.
135 </p>
135 </p>
136
136
137 <p>
137 <p>
138 The Windows installer was written by <a
138 The Windows installer was written by <a
139 href="http://www.serpentine.com/blog">Bryan O'Sullivan</a>.
139 href="http://www.serpentine.com/blog">Bryan O'Sullivan</a>.
140 </p>
140 </p>
141
141
142 <p>
142 <p>
143 Mercurial is Copyright 2005-2016 Matt Mackall and others. See
143 Mercurial is Copyright 2005-2017 Matt Mackall and others. See
144 the <tt>Contributors.txt</tt> file for a list of contributors.
144 the <tt>Contributors.txt</tt> file for a list of contributors.
145 </p>
145 </p>
146
146
147 <p>
147 <p>
148 Mercurial is free software; you can redistribute it and/or
148 Mercurial is free software; you can redistribute it and/or
149 modify it under the terms of the <a
149 modify it under the terms of the <a
150 href="http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt">GNU
150 href="http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt">GNU
151 General Public License version 2</a> or any later version.
151 General Public License version 2</a> or any later version.
152 </p>
152 </p>
153
153
154 <p>
154 <p>
155 Mercurial is distributed in the hope that it will be useful, but
155 Mercurial is distributed in the hope that it will be useful, but
156 <b>without any warranty</b>; without even the implied warranty
156 <b>without any warranty</b>; without even the implied warranty
157 of <b>merchantability</b> or <b>fitness for a particular
157 of <b>merchantability</b> or <b>fitness for a particular
158 purpose</b>. See the GNU General Public License for more
158 purpose</b>. See the GNU General Public License for more
159 details.
159 details.
160 </p>
160 </p>
161 </body>
161 </body>
162 </html>
162 </html>
@@ -1,120 +1,120 b''
1 ; Script generated by the Inno Setup Script Wizard.
1 ; Script generated by the Inno Setup Script Wizard.
2 ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
2 ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
3
3
4 #ifndef VERSION
4 #ifndef VERSION
5 #define FileHandle
5 #define FileHandle
6 #define FileLine
6 #define FileLine
7 #define VERSION = "unknown"
7 #define VERSION = "unknown"
8 #if FileHandle = FileOpen(SourcePath + "\..\..\mercurial\__version__.py")
8 #if FileHandle = FileOpen(SourcePath + "\..\..\mercurial\__version__.py")
9 #expr FileLine = FileRead(FileHandle)
9 #expr FileLine = FileRead(FileHandle)
10 #expr FileLine = FileRead(FileHandle)
10 #expr FileLine = FileRead(FileHandle)
11 #define VERSION = Copy(FileLine, Pos('"', FileLine)+1, Len(FileLine)-Pos('"', FileLine)-1)
11 #define VERSION = Copy(FileLine, Pos('"', FileLine)+1, Len(FileLine)-Pos('"', FileLine)-1)
12 #endif
12 #endif
13 #if FileHandle
13 #if FileHandle
14 #expr FileClose(FileHandle)
14 #expr FileClose(FileHandle)
15 #endif
15 #endif
16 #pragma message "Detected Version: " + VERSION
16 #pragma message "Detected Version: " + VERSION
17 #endif
17 #endif
18
18
19 #ifndef ARCH
19 #ifndef ARCH
20 #define ARCH = "x86"
20 #define ARCH = "x86"
21 #endif
21 #endif
22
22
23 [Setup]
23 [Setup]
24 AppCopyright=Copyright 2005-2016 Matt Mackall and others
24 AppCopyright=Copyright 2005-2017 Matt Mackall and others
25 AppName=Mercurial
25 AppName=Mercurial
26 AppVersion={#VERSION}
26 AppVersion={#VERSION}
27 #if ARCH == "x64"
27 #if ARCH == "x64"
28 AppVerName=Mercurial {#VERSION} (64-bit)
28 AppVerName=Mercurial {#VERSION} (64-bit)
29 OutputBaseFilename=Mercurial-{#VERSION}-x64
29 OutputBaseFilename=Mercurial-{#VERSION}-x64
30 ArchitecturesAllowed=x64
30 ArchitecturesAllowed=x64
31 ArchitecturesInstallIn64BitMode=x64
31 ArchitecturesInstallIn64BitMode=x64
32 #else
32 #else
33 AppVerName=Mercurial {#VERSION}
33 AppVerName=Mercurial {#VERSION}
34 OutputBaseFilename=Mercurial-{#VERSION}
34 OutputBaseFilename=Mercurial-{#VERSION}
35 #endif
35 #endif
36 InfoAfterFile=contrib/win32/postinstall.txt
36 InfoAfterFile=contrib/win32/postinstall.txt
37 LicenseFile=COPYING
37 LicenseFile=COPYING
38 ShowLanguageDialog=yes
38 ShowLanguageDialog=yes
39 AppPublisher=Matt Mackall and others
39 AppPublisher=Matt Mackall and others
40 AppPublisherURL=https://mercurial-scm.org/
40 AppPublisherURL=https://mercurial-scm.org/
41 AppSupportURL=https://mercurial-scm.org/
41 AppSupportURL=https://mercurial-scm.org/
42 AppUpdatesURL=https://mercurial-scm.org/
42 AppUpdatesURL=https://mercurial-scm.org/
43 AppID={{4B95A5F1-EF59-4B08-BED8-C891C46121B3}
43 AppID={{4B95A5F1-EF59-4B08-BED8-C891C46121B3}
44 AppContact=mercurial@mercurial-scm.org
44 AppContact=mercurial@mercurial-scm.org
45 DefaultDirName={pf}\Mercurial
45 DefaultDirName={pf}\Mercurial
46 SourceDir=..\..
46 SourceDir=..\..
47 VersionInfoDescription=Mercurial distributed SCM (version {#VERSION})
47 VersionInfoDescription=Mercurial distributed SCM (version {#VERSION})
48 VersionInfoCopyright=Copyright 2005-2016 Matt Mackall and others
48 VersionInfoCopyright=Copyright 2005-2017 Matt Mackall and others
49 VersionInfoCompany=Matt Mackall and others
49 VersionInfoCompany=Matt Mackall and others
50 InternalCompressLevel=max
50 InternalCompressLevel=max
51 SolidCompression=true
51 SolidCompression=true
52 SetupIconFile=contrib\win32\mercurial.ico
52 SetupIconFile=contrib\win32\mercurial.ico
53 AllowNoIcons=true
53 AllowNoIcons=true
54 DefaultGroupName=Mercurial
54 DefaultGroupName=Mercurial
55 PrivilegesRequired=none
55 PrivilegesRequired=none
56
56
57 [Files]
57 [Files]
58 Source: contrib\mercurial.el; DestDir: {app}/Contrib
58 Source: contrib\mercurial.el; DestDir: {app}/Contrib
59 Source: contrib\vim\*.*; DestDir: {app}/Contrib/Vim
59 Source: contrib\vim\*.*; DestDir: {app}/Contrib/Vim
60 Source: contrib\zsh_completion; DestDir: {app}/Contrib
60 Source: contrib\zsh_completion; DestDir: {app}/Contrib
61 Source: contrib\bash_completion; DestDir: {app}/Contrib
61 Source: contrib\bash_completion; DestDir: {app}/Contrib
62 Source: contrib\tcsh_completion; DestDir: {app}/Contrib
62 Source: contrib\tcsh_completion; DestDir: {app}/Contrib
63 Source: contrib\tcsh_completion_build.sh; DestDir: {app}/Contrib
63 Source: contrib\tcsh_completion_build.sh; DestDir: {app}/Contrib
64 Source: contrib\hgk; DestDir: {app}/Contrib; DestName: hgk.tcl
64 Source: contrib\hgk; DestDir: {app}/Contrib; DestName: hgk.tcl
65 Source: contrib\xml.rnc; DestDir: {app}/Contrib
65 Source: contrib\xml.rnc; DestDir: {app}/Contrib
66 Source: contrib\mercurial.el; DestDir: {app}/Contrib
66 Source: contrib\mercurial.el; DestDir: {app}/Contrib
67 Source: contrib\mq.el; DestDir: {app}/Contrib
67 Source: contrib\mq.el; DestDir: {app}/Contrib
68 Source: contrib\hgweb.fcgi; DestDir: {app}/Contrib
68 Source: contrib\hgweb.fcgi; DestDir: {app}/Contrib
69 Source: contrib\hgweb.wsgi; DestDir: {app}/Contrib
69 Source: contrib\hgweb.wsgi; DestDir: {app}/Contrib
70 Source: contrib\win32\ReadMe.html; DestDir: {app}; Flags: isreadme
70 Source: contrib\win32\ReadMe.html; DestDir: {app}; Flags: isreadme
71 Source: contrib\win32\postinstall.txt; DestDir: {app}; DestName: ReleaseNotes.txt
71 Source: contrib\win32\postinstall.txt; DestDir: {app}; DestName: ReleaseNotes.txt
72 Source: dist\hg.exe; DestDir: {app}; AfterInstall: Touch('{app}\hg.exe.local')
72 Source: dist\hg.exe; DestDir: {app}; AfterInstall: Touch('{app}\hg.exe.local')
73 #if ARCH == "x64"
73 #if ARCH == "x64"
74 Source: dist\lib\*.dll; Destdir: {app}\lib
74 Source: dist\lib\*.dll; Destdir: {app}\lib
75 Source: dist\lib\*.pyd; Destdir: {app}\lib
75 Source: dist\lib\*.pyd; Destdir: {app}\lib
76 #else
76 #else
77 Source: dist\w9xpopen.exe; DestDir: {app}
77 Source: dist\w9xpopen.exe; DestDir: {app}
78 #endif
78 #endif
79 Source: dist\python*.dll; Destdir: {app}; Flags: skipifsourcedoesntexist
79 Source: dist\python*.dll; Destdir: {app}; Flags: skipifsourcedoesntexist
80 Source: dist\msvc*.dll; DestDir: {app}; Flags: skipifsourcedoesntexist
80 Source: dist\msvc*.dll; DestDir: {app}; Flags: skipifsourcedoesntexist
81 Source: dist\Microsoft.VC*.CRT.manifest; DestDir: {app}; Flags: skipifsourcedoesntexist
81 Source: dist\Microsoft.VC*.CRT.manifest; DestDir: {app}; Flags: skipifsourcedoesntexist
82 Source: dist\lib\library.zip; DestDir: {app}\lib
82 Source: dist\lib\library.zip; DestDir: {app}\lib
83 Source: dist\add_path.exe; DestDir: {app}
83 Source: dist\add_path.exe; DestDir: {app}
84 Source: doc\*.html; DestDir: {app}\Docs
84 Source: doc\*.html; DestDir: {app}\Docs
85 Source: doc\style.css; DestDir: {app}\Docs
85 Source: doc\style.css; DestDir: {app}\Docs
86 Source: mercurial\help\*.txt; DestDir: {app}\help
86 Source: mercurial\help\*.txt; DestDir: {app}\help
87 Source: mercurial\help\internals\*.txt; DestDir: {app}\help\internals
87 Source: mercurial\help\internals\*.txt; DestDir: {app}\help\internals
88 Source: mercurial\default.d\*.rc; DestDir: {app}\default.d
88 Source: mercurial\default.d\*.rc; DestDir: {app}\default.d
89 Source: mercurial\locale\*.*; DestDir: {app}\locale; Flags: recursesubdirs createallsubdirs skipifsourcedoesntexist
89 Source: mercurial\locale\*.*; DestDir: {app}\locale; Flags: recursesubdirs createallsubdirs skipifsourcedoesntexist
90 Source: mercurial\templates\*.*; DestDir: {app}\Templates; Flags: recursesubdirs createallsubdirs
90 Source: mercurial\templates\*.*; DestDir: {app}\Templates; Flags: recursesubdirs createallsubdirs
91 Source: CONTRIBUTORS; DestDir: {app}; DestName: Contributors.txt
91 Source: CONTRIBUTORS; DestDir: {app}; DestName: Contributors.txt
92 Source: COPYING; DestDir: {app}; DestName: Copying.txt
92 Source: COPYING; DestDir: {app}; DestName: Copying.txt
93
93
94 [INI]
94 [INI]
95 Filename: {app}\Mercurial.url; Section: InternetShortcut; Key: URL; String: https://mercurial-scm.org/
95 Filename: {app}\Mercurial.url; Section: InternetShortcut; Key: URL; String: https://mercurial-scm.org/
96 Filename: {app}\default.d\editor.rc; Section: ui; Key: editor; String: notepad
96 Filename: {app}\default.d\editor.rc; Section: ui; Key: editor; String: notepad
97
97
98 [UninstallDelete]
98 [UninstallDelete]
99 Type: files; Name: {app}\Mercurial.url
99 Type: files; Name: {app}\Mercurial.url
100 Type: filesandordirs; Name: {app}\default.d
100 Type: filesandordirs; Name: {app}\default.d
101 Type: files; Name: "{app}\hg.exe.local"
101 Type: files; Name: "{app}\hg.exe.local"
102
102
103 [Icons]
103 [Icons]
104 Name: {group}\Uninstall Mercurial; Filename: {uninstallexe}
104 Name: {group}\Uninstall Mercurial; Filename: {uninstallexe}
105 Name: {group}\Mercurial Command Reference; Filename: {app}\Docs\hg.1.html
105 Name: {group}\Mercurial Command Reference; Filename: {app}\Docs\hg.1.html
106 Name: {group}\Mercurial Configuration Files; Filename: {app}\Docs\hgrc.5.html
106 Name: {group}\Mercurial Configuration Files; Filename: {app}\Docs\hgrc.5.html
107 Name: {group}\Mercurial Ignore Files; Filename: {app}\Docs\hgignore.5.html
107 Name: {group}\Mercurial Ignore Files; Filename: {app}\Docs\hgignore.5.html
108 Name: {group}\Mercurial Web Site; Filename: {app}\Mercurial.url
108 Name: {group}\Mercurial Web Site; Filename: {app}\Mercurial.url
109
109
110 [Run]
110 [Run]
111 Filename: "{app}\add_path.exe"; Parameters: "{app}"; Flags: postinstall; Description: "Add the installation path to the search path"
111 Filename: "{app}\add_path.exe"; Parameters: "{app}"; Flags: postinstall; Description: "Add the installation path to the search path"
112
112
113 [UninstallRun]
113 [UninstallRun]
114 Filename: "{app}\add_path.exe"; Parameters: "/del {app}"
114 Filename: "{app}\add_path.exe"; Parameters: "/del {app}"
115
115
116 [Code]
116 [Code]
117 procedure Touch(fn: String);
117 procedure Touch(fn: String);
118 begin
118 begin
119 SaveStringToFile(ExpandConstant(fn), '', False);
119 SaveStringToFile(ExpandConstant(fn), '', False);
120 end;
120 end;
@@ -1,6620 +1,6620 b''
1 # commands.py - command processing for mercurial
1 # commands.py - command processing for mercurial
2 #
2 #
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import difflib
10 import difflib
11 import errno
11 import errno
12 import os
12 import os
13 import re
13 import re
14 import socket
14 import socket
15 import string
15 import string
16 import sys
16 import sys
17 import tempfile
17 import tempfile
18 import time
18 import time
19
19
20 from .i18n import _
20 from .i18n import _
21 from .node import (
21 from .node import (
22 bin,
22 bin,
23 hex,
23 hex,
24 nullhex,
24 nullhex,
25 nullid,
25 nullid,
26 nullrev,
26 nullrev,
27 short,
27 short,
28 )
28 )
29 from . import (
29 from . import (
30 archival,
30 archival,
31 bookmarks,
31 bookmarks,
32 bundle2,
32 bundle2,
33 changegroup,
33 changegroup,
34 cmdutil,
34 cmdutil,
35 copies,
35 copies,
36 destutil,
36 destutil,
37 dirstateguard,
37 dirstateguard,
38 discovery,
38 discovery,
39 encoding,
39 encoding,
40 error,
40 error,
41 exchange,
41 exchange,
42 extensions,
42 extensions,
43 formatter,
43 formatter,
44 graphmod,
44 graphmod,
45 hbisect,
45 hbisect,
46 help,
46 help,
47 hg,
47 hg,
48 lock as lockmod,
48 lock as lockmod,
49 merge as mergemod,
49 merge as mergemod,
50 minirst,
50 minirst,
51 obsolete,
51 obsolete,
52 patch,
52 patch,
53 phases,
53 phases,
54 policy,
54 policy,
55 pvec,
55 pvec,
56 pycompat,
56 pycompat,
57 repair,
57 repair,
58 revlog,
58 revlog,
59 revset,
59 revset,
60 scmutil,
60 scmutil,
61 server,
61 server,
62 sshserver,
62 sshserver,
63 sslutil,
63 sslutil,
64 streamclone,
64 streamclone,
65 templatekw,
65 templatekw,
66 templater,
66 templater,
67 ui as uimod,
67 ui as uimod,
68 util,
68 util,
69 )
69 )
70
70
71 release = lockmod.release
71 release = lockmod.release
72
72
73 table = {}
73 table = {}
74
74
75 command = cmdutil.command(table)
75 command = cmdutil.command(table)
76
76
77 # label constants
77 # label constants
78 # until 3.5, bookmarks.current was the advertised name, not
78 # until 3.5, bookmarks.current was the advertised name, not
79 # bookmarks.active, so we must use both to avoid breaking old
79 # bookmarks.active, so we must use both to avoid breaking old
80 # custom styles
80 # custom styles
81 activebookmarklabel = 'bookmarks.active bookmarks.current'
81 activebookmarklabel = 'bookmarks.active bookmarks.current'
82
82
83 # common command options
83 # common command options
84
84
85 globalopts = [
85 globalopts = [
86 ('R', 'repository', '',
86 ('R', 'repository', '',
87 _('repository root directory or name of overlay bundle file'),
87 _('repository root directory or name of overlay bundle file'),
88 _('REPO')),
88 _('REPO')),
89 ('', 'cwd', '',
89 ('', 'cwd', '',
90 _('change working directory'), _('DIR')),
90 _('change working directory'), _('DIR')),
91 ('y', 'noninteractive', None,
91 ('y', 'noninteractive', None,
92 _('do not prompt, automatically pick the first choice for all prompts')),
92 _('do not prompt, automatically pick the first choice for all prompts')),
93 ('q', 'quiet', None, _('suppress output')),
93 ('q', 'quiet', None, _('suppress output')),
94 ('v', 'verbose', None, _('enable additional output')),
94 ('v', 'verbose', None, _('enable additional output')),
95 ('', 'config', [],
95 ('', 'config', [],
96 _('set/override config option (use \'section.name=value\')'),
96 _('set/override config option (use \'section.name=value\')'),
97 _('CONFIG')),
97 _('CONFIG')),
98 ('', 'debug', None, _('enable debugging output')),
98 ('', 'debug', None, _('enable debugging output')),
99 ('', 'debugger', None, _('start debugger')),
99 ('', 'debugger', None, _('start debugger')),
100 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
100 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
101 _('ENCODE')),
101 _('ENCODE')),
102 ('', 'encodingmode', encoding.encodingmode,
102 ('', 'encodingmode', encoding.encodingmode,
103 _('set the charset encoding mode'), _('MODE')),
103 _('set the charset encoding mode'), _('MODE')),
104 ('', 'traceback', None, _('always print a traceback on exception')),
104 ('', 'traceback', None, _('always print a traceback on exception')),
105 ('', 'time', None, _('time how long the command takes')),
105 ('', 'time', None, _('time how long the command takes')),
106 ('', 'profile', None, _('print command execution profile')),
106 ('', 'profile', None, _('print command execution profile')),
107 ('', 'version', None, _('output version information and exit')),
107 ('', 'version', None, _('output version information and exit')),
108 ('h', 'help', None, _('display help and exit')),
108 ('h', 'help', None, _('display help and exit')),
109 ('', 'hidden', False, _('consider hidden changesets')),
109 ('', 'hidden', False, _('consider hidden changesets')),
110 ]
110 ]
111
111
112 dryrunopts = [('n', 'dry-run', None,
112 dryrunopts = [('n', 'dry-run', None,
113 _('do not perform actions, just print output'))]
113 _('do not perform actions, just print output'))]
114
114
115 remoteopts = [
115 remoteopts = [
116 ('e', 'ssh', '',
116 ('e', 'ssh', '',
117 _('specify ssh command to use'), _('CMD')),
117 _('specify ssh command to use'), _('CMD')),
118 ('', 'remotecmd', '',
118 ('', 'remotecmd', '',
119 _('specify hg command to run on the remote side'), _('CMD')),
119 _('specify hg command to run on the remote side'), _('CMD')),
120 ('', 'insecure', None,
120 ('', 'insecure', None,
121 _('do not verify server certificate (ignoring web.cacerts config)')),
121 _('do not verify server certificate (ignoring web.cacerts config)')),
122 ]
122 ]
123
123
124 walkopts = [
124 walkopts = [
125 ('I', 'include', [],
125 ('I', 'include', [],
126 _('include names matching the given patterns'), _('PATTERN')),
126 _('include names matching the given patterns'), _('PATTERN')),
127 ('X', 'exclude', [],
127 ('X', 'exclude', [],
128 _('exclude names matching the given patterns'), _('PATTERN')),
128 _('exclude names matching the given patterns'), _('PATTERN')),
129 ]
129 ]
130
130
131 commitopts = [
131 commitopts = [
132 ('m', 'message', '',
132 ('m', 'message', '',
133 _('use text as commit message'), _('TEXT')),
133 _('use text as commit message'), _('TEXT')),
134 ('l', 'logfile', '',
134 ('l', 'logfile', '',
135 _('read commit message from file'), _('FILE')),
135 _('read commit message from file'), _('FILE')),
136 ]
136 ]
137
137
138 commitopts2 = [
138 commitopts2 = [
139 ('d', 'date', '',
139 ('d', 'date', '',
140 _('record the specified date as commit date'), _('DATE')),
140 _('record the specified date as commit date'), _('DATE')),
141 ('u', 'user', '',
141 ('u', 'user', '',
142 _('record the specified user as committer'), _('USER')),
142 _('record the specified user as committer'), _('USER')),
143 ]
143 ]
144
144
145 # hidden for now
145 # hidden for now
146 formatteropts = [
146 formatteropts = [
147 ('T', 'template', '',
147 ('T', 'template', '',
148 _('display with template (EXPERIMENTAL)'), _('TEMPLATE')),
148 _('display with template (EXPERIMENTAL)'), _('TEMPLATE')),
149 ]
149 ]
150
150
151 templateopts = [
151 templateopts = [
152 ('', 'style', '',
152 ('', 'style', '',
153 _('display using template map file (DEPRECATED)'), _('STYLE')),
153 _('display using template map file (DEPRECATED)'), _('STYLE')),
154 ('T', 'template', '',
154 ('T', 'template', '',
155 _('display with template'), _('TEMPLATE')),
155 _('display with template'), _('TEMPLATE')),
156 ]
156 ]
157
157
158 logopts = [
158 logopts = [
159 ('p', 'patch', None, _('show patch')),
159 ('p', 'patch', None, _('show patch')),
160 ('g', 'git', None, _('use git extended diff format')),
160 ('g', 'git', None, _('use git extended diff format')),
161 ('l', 'limit', '',
161 ('l', 'limit', '',
162 _('limit number of changes displayed'), _('NUM')),
162 _('limit number of changes displayed'), _('NUM')),
163 ('M', 'no-merges', None, _('do not show merges')),
163 ('M', 'no-merges', None, _('do not show merges')),
164 ('', 'stat', None, _('output diffstat-style summary of changes')),
164 ('', 'stat', None, _('output diffstat-style summary of changes')),
165 ('G', 'graph', None, _("show the revision DAG")),
165 ('G', 'graph', None, _("show the revision DAG")),
166 ] + templateopts
166 ] + templateopts
167
167
168 diffopts = [
168 diffopts = [
169 ('a', 'text', None, _('treat all files as text')),
169 ('a', 'text', None, _('treat all files as text')),
170 ('g', 'git', None, _('use git extended diff format')),
170 ('g', 'git', None, _('use git extended diff format')),
171 ('', 'nodates', None, _('omit dates from diff headers'))
171 ('', 'nodates', None, _('omit dates from diff headers'))
172 ]
172 ]
173
173
174 diffwsopts = [
174 diffwsopts = [
175 ('w', 'ignore-all-space', None,
175 ('w', 'ignore-all-space', None,
176 _('ignore white space when comparing lines')),
176 _('ignore white space when comparing lines')),
177 ('b', 'ignore-space-change', None,
177 ('b', 'ignore-space-change', None,
178 _('ignore changes in the amount of white space')),
178 _('ignore changes in the amount of white space')),
179 ('B', 'ignore-blank-lines', None,
179 ('B', 'ignore-blank-lines', None,
180 _('ignore changes whose lines are all blank')),
180 _('ignore changes whose lines are all blank')),
181 ]
181 ]
182
182
183 diffopts2 = [
183 diffopts2 = [
184 ('', 'noprefix', None, _('omit a/ and b/ prefixes from filenames')),
184 ('', 'noprefix', None, _('omit a/ and b/ prefixes from filenames')),
185 ('p', 'show-function', None, _('show which function each change is in')),
185 ('p', 'show-function', None, _('show which function each change is in')),
186 ('', 'reverse', None, _('produce a diff that undoes the changes')),
186 ('', 'reverse', None, _('produce a diff that undoes the changes')),
187 ] + diffwsopts + [
187 ] + diffwsopts + [
188 ('U', 'unified', '',
188 ('U', 'unified', '',
189 _('number of lines of context to show'), _('NUM')),
189 _('number of lines of context to show'), _('NUM')),
190 ('', 'stat', None, _('output diffstat-style summary of changes')),
190 ('', 'stat', None, _('output diffstat-style summary of changes')),
191 ('', 'root', '', _('produce diffs relative to subdirectory'), _('DIR')),
191 ('', 'root', '', _('produce diffs relative to subdirectory'), _('DIR')),
192 ]
192 ]
193
193
194 mergetoolopts = [
194 mergetoolopts = [
195 ('t', 'tool', '', _('specify merge tool')),
195 ('t', 'tool', '', _('specify merge tool')),
196 ]
196 ]
197
197
198 similarityopts = [
198 similarityopts = [
199 ('s', 'similarity', '',
199 ('s', 'similarity', '',
200 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
200 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
201 ]
201 ]
202
202
203 subrepoopts = [
203 subrepoopts = [
204 ('S', 'subrepos', None,
204 ('S', 'subrepos', None,
205 _('recurse into subrepositories'))
205 _('recurse into subrepositories'))
206 ]
206 ]
207
207
208 debugrevlogopts = [
208 debugrevlogopts = [
209 ('c', 'changelog', False, _('open changelog')),
209 ('c', 'changelog', False, _('open changelog')),
210 ('m', 'manifest', False, _('open manifest')),
210 ('m', 'manifest', False, _('open manifest')),
211 ('', 'dir', '', _('open directory manifest')),
211 ('', 'dir', '', _('open directory manifest')),
212 ]
212 ]
213
213
214 # Commands start here, listed alphabetically
214 # Commands start here, listed alphabetically
215
215
216 @command('^add',
216 @command('^add',
217 walkopts + subrepoopts + dryrunopts,
217 walkopts + subrepoopts + dryrunopts,
218 _('[OPTION]... [FILE]...'),
218 _('[OPTION]... [FILE]...'),
219 inferrepo=True)
219 inferrepo=True)
220 def add(ui, repo, *pats, **opts):
220 def add(ui, repo, *pats, **opts):
221 """add the specified files on the next commit
221 """add the specified files on the next commit
222
222
223 Schedule files to be version controlled and added to the
223 Schedule files to be version controlled and added to the
224 repository.
224 repository.
225
225
226 The files will be added to the repository at the next commit. To
226 The files will be added to the repository at the next commit. To
227 undo an add before that, see :hg:`forget`.
227 undo an add before that, see :hg:`forget`.
228
228
229 If no names are given, add all files to the repository (except
229 If no names are given, add all files to the repository (except
230 files matching ``.hgignore``).
230 files matching ``.hgignore``).
231
231
232 .. container:: verbose
232 .. container:: verbose
233
233
234 Examples:
234 Examples:
235
235
236 - New (unknown) files are added
236 - New (unknown) files are added
237 automatically by :hg:`add`::
237 automatically by :hg:`add`::
238
238
239 $ ls
239 $ ls
240 foo.c
240 foo.c
241 $ hg status
241 $ hg status
242 ? foo.c
242 ? foo.c
243 $ hg add
243 $ hg add
244 adding foo.c
244 adding foo.c
245 $ hg status
245 $ hg status
246 A foo.c
246 A foo.c
247
247
248 - Specific files to be added can be specified::
248 - Specific files to be added can be specified::
249
249
250 $ ls
250 $ ls
251 bar.c foo.c
251 bar.c foo.c
252 $ hg status
252 $ hg status
253 ? bar.c
253 ? bar.c
254 ? foo.c
254 ? foo.c
255 $ hg add bar.c
255 $ hg add bar.c
256 $ hg status
256 $ hg status
257 A bar.c
257 A bar.c
258 ? foo.c
258 ? foo.c
259
259
260 Returns 0 if all files are successfully added.
260 Returns 0 if all files are successfully added.
261 """
261 """
262
262
263 m = scmutil.match(repo[None], pats, opts)
263 m = scmutil.match(repo[None], pats, opts)
264 rejected = cmdutil.add(ui, repo, m, "", False, **opts)
264 rejected = cmdutil.add(ui, repo, m, "", False, **opts)
265 return rejected and 1 or 0
265 return rejected and 1 or 0
266
266
267 @command('addremove',
267 @command('addremove',
268 similarityopts + subrepoopts + walkopts + dryrunopts,
268 similarityopts + subrepoopts + walkopts + dryrunopts,
269 _('[OPTION]... [FILE]...'),
269 _('[OPTION]... [FILE]...'),
270 inferrepo=True)
270 inferrepo=True)
271 def addremove(ui, repo, *pats, **opts):
271 def addremove(ui, repo, *pats, **opts):
272 """add all new files, delete all missing files
272 """add all new files, delete all missing files
273
273
274 Add all new files and remove all missing files from the
274 Add all new files and remove all missing files from the
275 repository.
275 repository.
276
276
277 Unless names are given, new files are ignored if they match any of
277 Unless names are given, new files are ignored if they match any of
278 the patterns in ``.hgignore``. As with add, these changes take
278 the patterns in ``.hgignore``. As with add, these changes take
279 effect at the next commit.
279 effect at the next commit.
280
280
281 Use the -s/--similarity option to detect renamed files. This
281 Use the -s/--similarity option to detect renamed files. This
282 option takes a percentage between 0 (disabled) and 100 (files must
282 option takes a percentage between 0 (disabled) and 100 (files must
283 be identical) as its parameter. With a parameter greater than 0,
283 be identical) as its parameter. With a parameter greater than 0,
284 this compares every removed file with every added file and records
284 this compares every removed file with every added file and records
285 those similar enough as renames. Detecting renamed files this way
285 those similar enough as renames. Detecting renamed files this way
286 can be expensive. After using this option, :hg:`status -C` can be
286 can be expensive. After using this option, :hg:`status -C` can be
287 used to check which files were identified as moved or renamed. If
287 used to check which files were identified as moved or renamed. If
288 not specified, -s/--similarity defaults to 100 and only renames of
288 not specified, -s/--similarity defaults to 100 and only renames of
289 identical files are detected.
289 identical files are detected.
290
290
291 .. container:: verbose
291 .. container:: verbose
292
292
293 Examples:
293 Examples:
294
294
295 - A number of files (bar.c and foo.c) are new,
295 - A number of files (bar.c and foo.c) are new,
296 while foobar.c has been removed (without using :hg:`remove`)
296 while foobar.c has been removed (without using :hg:`remove`)
297 from the repository::
297 from the repository::
298
298
299 $ ls
299 $ ls
300 bar.c foo.c
300 bar.c foo.c
301 $ hg status
301 $ hg status
302 ! foobar.c
302 ! foobar.c
303 ? bar.c
303 ? bar.c
304 ? foo.c
304 ? foo.c
305 $ hg addremove
305 $ hg addremove
306 adding bar.c
306 adding bar.c
307 adding foo.c
307 adding foo.c
308 removing foobar.c
308 removing foobar.c
309 $ hg status
309 $ hg status
310 A bar.c
310 A bar.c
311 A foo.c
311 A foo.c
312 R foobar.c
312 R foobar.c
313
313
314 - A file foobar.c was moved to foo.c without using :hg:`rename`.
314 - A file foobar.c was moved to foo.c without using :hg:`rename`.
315 Afterwards, it was edited slightly::
315 Afterwards, it was edited slightly::
316
316
317 $ ls
317 $ ls
318 foo.c
318 foo.c
319 $ hg status
319 $ hg status
320 ! foobar.c
320 ! foobar.c
321 ? foo.c
321 ? foo.c
322 $ hg addremove --similarity 90
322 $ hg addremove --similarity 90
323 removing foobar.c
323 removing foobar.c
324 adding foo.c
324 adding foo.c
325 recording removal of foobar.c as rename to foo.c (94% similar)
325 recording removal of foobar.c as rename to foo.c (94% similar)
326 $ hg status -C
326 $ hg status -C
327 A foo.c
327 A foo.c
328 foobar.c
328 foobar.c
329 R foobar.c
329 R foobar.c
330
330
331 Returns 0 if all files are successfully added.
331 Returns 0 if all files are successfully added.
332 """
332 """
333 try:
333 try:
334 sim = float(opts.get('similarity') or 100)
334 sim = float(opts.get('similarity') or 100)
335 except ValueError:
335 except ValueError:
336 raise error.Abort(_('similarity must be a number'))
336 raise error.Abort(_('similarity must be a number'))
337 if sim < 0 or sim > 100:
337 if sim < 0 or sim > 100:
338 raise error.Abort(_('similarity must be between 0 and 100'))
338 raise error.Abort(_('similarity must be between 0 and 100'))
339 matcher = scmutil.match(repo[None], pats, opts)
339 matcher = scmutil.match(repo[None], pats, opts)
340 return scmutil.addremove(repo, matcher, "", opts, similarity=sim / 100.0)
340 return scmutil.addremove(repo, matcher, "", opts, similarity=sim / 100.0)
341
341
342 @command('^annotate|blame',
342 @command('^annotate|blame',
343 [('r', 'rev', '', _('annotate the specified revision'), _('REV')),
343 [('r', 'rev', '', _('annotate the specified revision'), _('REV')),
344 ('', 'follow', None,
344 ('', 'follow', None,
345 _('follow copies/renames and list the filename (DEPRECATED)')),
345 _('follow copies/renames and list the filename (DEPRECATED)')),
346 ('', 'no-follow', None, _("don't follow copies and renames")),
346 ('', 'no-follow', None, _("don't follow copies and renames")),
347 ('a', 'text', None, _('treat all files as text')),
347 ('a', 'text', None, _('treat all files as text')),
348 ('u', 'user', None, _('list the author (long with -v)')),
348 ('u', 'user', None, _('list the author (long with -v)')),
349 ('f', 'file', None, _('list the filename')),
349 ('f', 'file', None, _('list the filename')),
350 ('d', 'date', None, _('list the date (short with -q)')),
350 ('d', 'date', None, _('list the date (short with -q)')),
351 ('n', 'number', None, _('list the revision number (default)')),
351 ('n', 'number', None, _('list the revision number (default)')),
352 ('c', 'changeset', None, _('list the changeset')),
352 ('c', 'changeset', None, _('list the changeset')),
353 ('l', 'line-number', None, _('show line number at the first appearance'))
353 ('l', 'line-number', None, _('show line number at the first appearance'))
354 ] + diffwsopts + walkopts + formatteropts,
354 ] + diffwsopts + walkopts + formatteropts,
355 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'),
355 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'),
356 inferrepo=True)
356 inferrepo=True)
357 def annotate(ui, repo, *pats, **opts):
357 def annotate(ui, repo, *pats, **opts):
358 """show changeset information by line for each file
358 """show changeset information by line for each file
359
359
360 List changes in files, showing the revision id responsible for
360 List changes in files, showing the revision id responsible for
361 each line.
361 each line.
362
362
363 This command is useful for discovering when a change was made and
363 This command is useful for discovering when a change was made and
364 by whom.
364 by whom.
365
365
366 If you include --file, --user, or --date, the revision number is
366 If you include --file, --user, or --date, the revision number is
367 suppressed unless you also include --number.
367 suppressed unless you also include --number.
368
368
369 Without the -a/--text option, annotate will avoid processing files
369 Without the -a/--text option, annotate will avoid processing files
370 it detects as binary. With -a, annotate will annotate the file
370 it detects as binary. With -a, annotate will annotate the file
371 anyway, although the results will probably be neither useful
371 anyway, although the results will probably be neither useful
372 nor desirable.
372 nor desirable.
373
373
374 Returns 0 on success.
374 Returns 0 on success.
375 """
375 """
376 if not pats:
376 if not pats:
377 raise error.Abort(_('at least one filename or pattern is required'))
377 raise error.Abort(_('at least one filename or pattern is required'))
378
378
379 if opts.get('follow'):
379 if opts.get('follow'):
380 # --follow is deprecated and now just an alias for -f/--file
380 # --follow is deprecated and now just an alias for -f/--file
381 # to mimic the behavior of Mercurial before version 1.5
381 # to mimic the behavior of Mercurial before version 1.5
382 opts['file'] = True
382 opts['file'] = True
383
383
384 ctx = scmutil.revsingle(repo, opts.get('rev'))
384 ctx = scmutil.revsingle(repo, opts.get('rev'))
385
385
386 fm = ui.formatter('annotate', opts)
386 fm = ui.formatter('annotate', opts)
387 if ui.quiet:
387 if ui.quiet:
388 datefunc = util.shortdate
388 datefunc = util.shortdate
389 else:
389 else:
390 datefunc = util.datestr
390 datefunc = util.datestr
391 if ctx.rev() is None:
391 if ctx.rev() is None:
392 def hexfn(node):
392 def hexfn(node):
393 if node is None:
393 if node is None:
394 return None
394 return None
395 else:
395 else:
396 return fm.hexfunc(node)
396 return fm.hexfunc(node)
397 if opts.get('changeset'):
397 if opts.get('changeset'):
398 # omit "+" suffix which is appended to node hex
398 # omit "+" suffix which is appended to node hex
399 def formatrev(rev):
399 def formatrev(rev):
400 if rev is None:
400 if rev is None:
401 return '%d' % ctx.p1().rev()
401 return '%d' % ctx.p1().rev()
402 else:
402 else:
403 return '%d' % rev
403 return '%d' % rev
404 else:
404 else:
405 def formatrev(rev):
405 def formatrev(rev):
406 if rev is None:
406 if rev is None:
407 return '%d+' % ctx.p1().rev()
407 return '%d+' % ctx.p1().rev()
408 else:
408 else:
409 return '%d ' % rev
409 return '%d ' % rev
410 def formathex(hex):
410 def formathex(hex):
411 if hex is None:
411 if hex is None:
412 return '%s+' % fm.hexfunc(ctx.p1().node())
412 return '%s+' % fm.hexfunc(ctx.p1().node())
413 else:
413 else:
414 return '%s ' % hex
414 return '%s ' % hex
415 else:
415 else:
416 hexfn = fm.hexfunc
416 hexfn = fm.hexfunc
417 formatrev = formathex = str
417 formatrev = formathex = str
418
418
419 opmap = [('user', ' ', lambda x: x[0].user(), ui.shortuser),
419 opmap = [('user', ' ', lambda x: x[0].user(), ui.shortuser),
420 ('number', ' ', lambda x: x[0].rev(), formatrev),
420 ('number', ' ', lambda x: x[0].rev(), formatrev),
421 ('changeset', ' ', lambda x: hexfn(x[0].node()), formathex),
421 ('changeset', ' ', lambda x: hexfn(x[0].node()), formathex),
422 ('date', ' ', lambda x: x[0].date(), util.cachefunc(datefunc)),
422 ('date', ' ', lambda x: x[0].date(), util.cachefunc(datefunc)),
423 ('file', ' ', lambda x: x[0].path(), str),
423 ('file', ' ', lambda x: x[0].path(), str),
424 ('line_number', ':', lambda x: x[1], str),
424 ('line_number', ':', lambda x: x[1], str),
425 ]
425 ]
426 fieldnamemap = {'number': 'rev', 'changeset': 'node'}
426 fieldnamemap = {'number': 'rev', 'changeset': 'node'}
427
427
428 if (not opts.get('user') and not opts.get('changeset')
428 if (not opts.get('user') and not opts.get('changeset')
429 and not opts.get('date') and not opts.get('file')):
429 and not opts.get('date') and not opts.get('file')):
430 opts['number'] = True
430 opts['number'] = True
431
431
432 linenumber = opts.get('line_number') is not None
432 linenumber = opts.get('line_number') is not None
433 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
433 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
434 raise error.Abort(_('at least one of -n/-c is required for -l'))
434 raise error.Abort(_('at least one of -n/-c is required for -l'))
435
435
436 if fm.isplain():
436 if fm.isplain():
437 def makefunc(get, fmt):
437 def makefunc(get, fmt):
438 return lambda x: fmt(get(x))
438 return lambda x: fmt(get(x))
439 else:
439 else:
440 def makefunc(get, fmt):
440 def makefunc(get, fmt):
441 return get
441 return get
442 funcmap = [(makefunc(get, fmt), sep) for op, sep, get, fmt in opmap
442 funcmap = [(makefunc(get, fmt), sep) for op, sep, get, fmt in opmap
443 if opts.get(op)]
443 if opts.get(op)]
444 funcmap[0] = (funcmap[0][0], '') # no separator in front of first column
444 funcmap[0] = (funcmap[0][0], '') # no separator in front of first column
445 fields = ' '.join(fieldnamemap.get(op, op) for op, sep, get, fmt in opmap
445 fields = ' '.join(fieldnamemap.get(op, op) for op, sep, get, fmt in opmap
446 if opts.get(op))
446 if opts.get(op))
447
447
448 def bad(x, y):
448 def bad(x, y):
449 raise error.Abort("%s: %s" % (x, y))
449 raise error.Abort("%s: %s" % (x, y))
450
450
451 m = scmutil.match(ctx, pats, opts, badfn=bad)
451 m = scmutil.match(ctx, pats, opts, badfn=bad)
452
452
453 follow = not opts.get('no_follow')
453 follow = not opts.get('no_follow')
454 diffopts = patch.difffeatureopts(ui, opts, section='annotate',
454 diffopts = patch.difffeatureopts(ui, opts, section='annotate',
455 whitespace=True)
455 whitespace=True)
456 for abs in ctx.walk(m):
456 for abs in ctx.walk(m):
457 fctx = ctx[abs]
457 fctx = ctx[abs]
458 if not opts.get('text') and util.binary(fctx.data()):
458 if not opts.get('text') and util.binary(fctx.data()):
459 fm.plain(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
459 fm.plain(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
460 continue
460 continue
461
461
462 lines = fctx.annotate(follow=follow, linenumber=linenumber,
462 lines = fctx.annotate(follow=follow, linenumber=linenumber,
463 diffopts=diffopts)
463 diffopts=diffopts)
464 if not lines:
464 if not lines:
465 continue
465 continue
466 formats = []
466 formats = []
467 pieces = []
467 pieces = []
468
468
469 for f, sep in funcmap:
469 for f, sep in funcmap:
470 l = [f(n) for n, dummy in lines]
470 l = [f(n) for n, dummy in lines]
471 if fm.isplain():
471 if fm.isplain():
472 sizes = [encoding.colwidth(x) for x in l]
472 sizes = [encoding.colwidth(x) for x in l]
473 ml = max(sizes)
473 ml = max(sizes)
474 formats.append([sep + ' ' * (ml - w) + '%s' for w in sizes])
474 formats.append([sep + ' ' * (ml - w) + '%s' for w in sizes])
475 else:
475 else:
476 formats.append(['%s' for x in l])
476 formats.append(['%s' for x in l])
477 pieces.append(l)
477 pieces.append(l)
478
478
479 for f, p, l in zip(zip(*formats), zip(*pieces), lines):
479 for f, p, l in zip(zip(*formats), zip(*pieces), lines):
480 fm.startitem()
480 fm.startitem()
481 fm.write(fields, "".join(f), *p)
481 fm.write(fields, "".join(f), *p)
482 fm.write('line', ": %s", l[1])
482 fm.write('line', ": %s", l[1])
483
483
484 if not lines[-1][1].endswith('\n'):
484 if not lines[-1][1].endswith('\n'):
485 fm.plain('\n')
485 fm.plain('\n')
486
486
487 fm.end()
487 fm.end()
488
488
489 @command('archive',
489 @command('archive',
490 [('', 'no-decode', None, _('do not pass files through decoders')),
490 [('', 'no-decode', None, _('do not pass files through decoders')),
491 ('p', 'prefix', '', _('directory prefix for files in archive'),
491 ('p', 'prefix', '', _('directory prefix for files in archive'),
492 _('PREFIX')),
492 _('PREFIX')),
493 ('r', 'rev', '', _('revision to distribute'), _('REV')),
493 ('r', 'rev', '', _('revision to distribute'), _('REV')),
494 ('t', 'type', '', _('type of distribution to create'), _('TYPE')),
494 ('t', 'type', '', _('type of distribution to create'), _('TYPE')),
495 ] + subrepoopts + walkopts,
495 ] + subrepoopts + walkopts,
496 _('[OPTION]... DEST'))
496 _('[OPTION]... DEST'))
497 def archive(ui, repo, dest, **opts):
497 def archive(ui, repo, dest, **opts):
498 '''create an unversioned archive of a repository revision
498 '''create an unversioned archive of a repository revision
499
499
500 By default, the revision used is the parent of the working
500 By default, the revision used is the parent of the working
501 directory; use -r/--rev to specify a different revision.
501 directory; use -r/--rev to specify a different revision.
502
502
503 The archive type is automatically detected based on file
503 The archive type is automatically detected based on file
504 extension (to override, use -t/--type).
504 extension (to override, use -t/--type).
505
505
506 .. container:: verbose
506 .. container:: verbose
507
507
508 Examples:
508 Examples:
509
509
510 - create a zip file containing the 1.0 release::
510 - create a zip file containing the 1.0 release::
511
511
512 hg archive -r 1.0 project-1.0.zip
512 hg archive -r 1.0 project-1.0.zip
513
513
514 - create a tarball excluding .hg files::
514 - create a tarball excluding .hg files::
515
515
516 hg archive project.tar.gz -X ".hg*"
516 hg archive project.tar.gz -X ".hg*"
517
517
518 Valid types are:
518 Valid types are:
519
519
520 :``files``: a directory full of files (default)
520 :``files``: a directory full of files (default)
521 :``tar``: tar archive, uncompressed
521 :``tar``: tar archive, uncompressed
522 :``tbz2``: tar archive, compressed using bzip2
522 :``tbz2``: tar archive, compressed using bzip2
523 :``tgz``: tar archive, compressed using gzip
523 :``tgz``: tar archive, compressed using gzip
524 :``uzip``: zip archive, uncompressed
524 :``uzip``: zip archive, uncompressed
525 :``zip``: zip archive, compressed using deflate
525 :``zip``: zip archive, compressed using deflate
526
526
527 The exact name of the destination archive or directory is given
527 The exact name of the destination archive or directory is given
528 using a format string; see :hg:`help export` for details.
528 using a format string; see :hg:`help export` for details.
529
529
530 Each member added to an archive file has a directory prefix
530 Each member added to an archive file has a directory prefix
531 prepended. Use -p/--prefix to specify a format string for the
531 prepended. Use -p/--prefix to specify a format string for the
532 prefix. The default is the basename of the archive, with suffixes
532 prefix. The default is the basename of the archive, with suffixes
533 removed.
533 removed.
534
534
535 Returns 0 on success.
535 Returns 0 on success.
536 '''
536 '''
537
537
538 ctx = scmutil.revsingle(repo, opts.get('rev'))
538 ctx = scmutil.revsingle(repo, opts.get('rev'))
539 if not ctx:
539 if not ctx:
540 raise error.Abort(_('no working directory: please specify a revision'))
540 raise error.Abort(_('no working directory: please specify a revision'))
541 node = ctx.node()
541 node = ctx.node()
542 dest = cmdutil.makefilename(repo, dest, node)
542 dest = cmdutil.makefilename(repo, dest, node)
543 if os.path.realpath(dest) == repo.root:
543 if os.path.realpath(dest) == repo.root:
544 raise error.Abort(_('repository root cannot be destination'))
544 raise error.Abort(_('repository root cannot be destination'))
545
545
546 kind = opts.get('type') or archival.guesskind(dest) or 'files'
546 kind = opts.get('type') or archival.guesskind(dest) or 'files'
547 prefix = opts.get('prefix')
547 prefix = opts.get('prefix')
548
548
549 if dest == '-':
549 if dest == '-':
550 if kind == 'files':
550 if kind == 'files':
551 raise error.Abort(_('cannot archive plain files to stdout'))
551 raise error.Abort(_('cannot archive plain files to stdout'))
552 dest = cmdutil.makefileobj(repo, dest)
552 dest = cmdutil.makefileobj(repo, dest)
553 if not prefix:
553 if not prefix:
554 prefix = os.path.basename(repo.root) + '-%h'
554 prefix = os.path.basename(repo.root) + '-%h'
555
555
556 prefix = cmdutil.makefilename(repo, prefix, node)
556 prefix = cmdutil.makefilename(repo, prefix, node)
557 matchfn = scmutil.match(ctx, [], opts)
557 matchfn = scmutil.match(ctx, [], opts)
558 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
558 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
559 matchfn, prefix, subrepos=opts.get('subrepos'))
559 matchfn, prefix, subrepos=opts.get('subrepos'))
560
560
561 @command('backout',
561 @command('backout',
562 [('', 'merge', None, _('merge with old dirstate parent after backout')),
562 [('', 'merge', None, _('merge with old dirstate parent after backout')),
563 ('', 'commit', None,
563 ('', 'commit', None,
564 _('commit if no conflicts were encountered (DEPRECATED)')),
564 _('commit if no conflicts were encountered (DEPRECATED)')),
565 ('', 'no-commit', None, _('do not commit')),
565 ('', 'no-commit', None, _('do not commit')),
566 ('', 'parent', '',
566 ('', 'parent', '',
567 _('parent to choose when backing out merge (DEPRECATED)'), _('REV')),
567 _('parent to choose when backing out merge (DEPRECATED)'), _('REV')),
568 ('r', 'rev', '', _('revision to backout'), _('REV')),
568 ('r', 'rev', '', _('revision to backout'), _('REV')),
569 ('e', 'edit', False, _('invoke editor on commit messages')),
569 ('e', 'edit', False, _('invoke editor on commit messages')),
570 ] + mergetoolopts + walkopts + commitopts + commitopts2,
570 ] + mergetoolopts + walkopts + commitopts + commitopts2,
571 _('[OPTION]... [-r] REV'))
571 _('[OPTION]... [-r] REV'))
572 def backout(ui, repo, node=None, rev=None, **opts):
572 def backout(ui, repo, node=None, rev=None, **opts):
573 '''reverse effect of earlier changeset
573 '''reverse effect of earlier changeset
574
574
575 Prepare a new changeset with the effect of REV undone in the
575 Prepare a new changeset with the effect of REV undone in the
576 current working directory. If no conflicts were encountered,
576 current working directory. If no conflicts were encountered,
577 it will be committed immediately.
577 it will be committed immediately.
578
578
579 If REV is the parent of the working directory, then this new changeset
579 If REV is the parent of the working directory, then this new changeset
580 is committed automatically (unless --no-commit is specified).
580 is committed automatically (unless --no-commit is specified).
581
581
582 .. note::
582 .. note::
583
583
584 :hg:`backout` cannot be used to fix either an unwanted or
584 :hg:`backout` cannot be used to fix either an unwanted or
585 incorrect merge.
585 incorrect merge.
586
586
587 .. container:: verbose
587 .. container:: verbose
588
588
589 Examples:
589 Examples:
590
590
591 - Reverse the effect of the parent of the working directory.
591 - Reverse the effect of the parent of the working directory.
592 This backout will be committed immediately::
592 This backout will be committed immediately::
593
593
594 hg backout -r .
594 hg backout -r .
595
595
596 - Reverse the effect of previous bad revision 23::
596 - Reverse the effect of previous bad revision 23::
597
597
598 hg backout -r 23
598 hg backout -r 23
599
599
600 - Reverse the effect of previous bad revision 23 and
600 - Reverse the effect of previous bad revision 23 and
601 leave changes uncommitted::
601 leave changes uncommitted::
602
602
603 hg backout -r 23 --no-commit
603 hg backout -r 23 --no-commit
604 hg commit -m "Backout revision 23"
604 hg commit -m "Backout revision 23"
605
605
606 By default, the pending changeset will have one parent,
606 By default, the pending changeset will have one parent,
607 maintaining a linear history. With --merge, the pending
607 maintaining a linear history. With --merge, the pending
608 changeset will instead have two parents: the old parent of the
608 changeset will instead have two parents: the old parent of the
609 working directory and a new child of REV that simply undoes REV.
609 working directory and a new child of REV that simply undoes REV.
610
610
611 Before version 1.7, the behavior without --merge was equivalent
611 Before version 1.7, the behavior without --merge was equivalent
612 to specifying --merge followed by :hg:`update --clean .` to
612 to specifying --merge followed by :hg:`update --clean .` to
613 cancel the merge and leave the child of REV as a head to be
613 cancel the merge and leave the child of REV as a head to be
614 merged separately.
614 merged separately.
615
615
616 See :hg:`help dates` for a list of formats valid for -d/--date.
616 See :hg:`help dates` for a list of formats valid for -d/--date.
617
617
618 See :hg:`help revert` for a way to restore files to the state
618 See :hg:`help revert` for a way to restore files to the state
619 of another revision.
619 of another revision.
620
620
621 Returns 0 on success, 1 if nothing to backout or there are unresolved
621 Returns 0 on success, 1 if nothing to backout or there are unresolved
622 files.
622 files.
623 '''
623 '''
624 wlock = lock = None
624 wlock = lock = None
625 try:
625 try:
626 wlock = repo.wlock()
626 wlock = repo.wlock()
627 lock = repo.lock()
627 lock = repo.lock()
628 return _dobackout(ui, repo, node, rev, **opts)
628 return _dobackout(ui, repo, node, rev, **opts)
629 finally:
629 finally:
630 release(lock, wlock)
630 release(lock, wlock)
631
631
632 def _dobackout(ui, repo, node=None, rev=None, **opts):
632 def _dobackout(ui, repo, node=None, rev=None, **opts):
633 if opts.get('commit') and opts.get('no_commit'):
633 if opts.get('commit') and opts.get('no_commit'):
634 raise error.Abort(_("cannot use --commit with --no-commit"))
634 raise error.Abort(_("cannot use --commit with --no-commit"))
635 if opts.get('merge') and opts.get('no_commit'):
635 if opts.get('merge') and opts.get('no_commit'):
636 raise error.Abort(_("cannot use --merge with --no-commit"))
636 raise error.Abort(_("cannot use --merge with --no-commit"))
637
637
638 if rev and node:
638 if rev and node:
639 raise error.Abort(_("please specify just one revision"))
639 raise error.Abort(_("please specify just one revision"))
640
640
641 if not rev:
641 if not rev:
642 rev = node
642 rev = node
643
643
644 if not rev:
644 if not rev:
645 raise error.Abort(_("please specify a revision to backout"))
645 raise error.Abort(_("please specify a revision to backout"))
646
646
647 date = opts.get('date')
647 date = opts.get('date')
648 if date:
648 if date:
649 opts['date'] = util.parsedate(date)
649 opts['date'] = util.parsedate(date)
650
650
651 cmdutil.checkunfinished(repo)
651 cmdutil.checkunfinished(repo)
652 cmdutil.bailifchanged(repo)
652 cmdutil.bailifchanged(repo)
653 node = scmutil.revsingle(repo, rev).node()
653 node = scmutil.revsingle(repo, rev).node()
654
654
655 op1, op2 = repo.dirstate.parents()
655 op1, op2 = repo.dirstate.parents()
656 if not repo.changelog.isancestor(node, op1):
656 if not repo.changelog.isancestor(node, op1):
657 raise error.Abort(_('cannot backout change that is not an ancestor'))
657 raise error.Abort(_('cannot backout change that is not an ancestor'))
658
658
659 p1, p2 = repo.changelog.parents(node)
659 p1, p2 = repo.changelog.parents(node)
660 if p1 == nullid:
660 if p1 == nullid:
661 raise error.Abort(_('cannot backout a change with no parents'))
661 raise error.Abort(_('cannot backout a change with no parents'))
662 if p2 != nullid:
662 if p2 != nullid:
663 if not opts.get('parent'):
663 if not opts.get('parent'):
664 raise error.Abort(_('cannot backout a merge changeset'))
664 raise error.Abort(_('cannot backout a merge changeset'))
665 p = repo.lookup(opts['parent'])
665 p = repo.lookup(opts['parent'])
666 if p not in (p1, p2):
666 if p not in (p1, p2):
667 raise error.Abort(_('%s is not a parent of %s') %
667 raise error.Abort(_('%s is not a parent of %s') %
668 (short(p), short(node)))
668 (short(p), short(node)))
669 parent = p
669 parent = p
670 else:
670 else:
671 if opts.get('parent'):
671 if opts.get('parent'):
672 raise error.Abort(_('cannot use --parent on non-merge changeset'))
672 raise error.Abort(_('cannot use --parent on non-merge changeset'))
673 parent = p1
673 parent = p1
674
674
675 # the backout should appear on the same branch
675 # the backout should appear on the same branch
676 branch = repo.dirstate.branch()
676 branch = repo.dirstate.branch()
677 bheads = repo.branchheads(branch)
677 bheads = repo.branchheads(branch)
678 rctx = scmutil.revsingle(repo, hex(parent))
678 rctx = scmutil.revsingle(repo, hex(parent))
679 if not opts.get('merge') and op1 != node:
679 if not opts.get('merge') and op1 != node:
680 dsguard = dirstateguard.dirstateguard(repo, 'backout')
680 dsguard = dirstateguard.dirstateguard(repo, 'backout')
681 try:
681 try:
682 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
682 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
683 'backout')
683 'backout')
684 stats = mergemod.update(repo, parent, True, True, node, False)
684 stats = mergemod.update(repo, parent, True, True, node, False)
685 repo.setparents(op1, op2)
685 repo.setparents(op1, op2)
686 dsguard.close()
686 dsguard.close()
687 hg._showstats(repo, stats)
687 hg._showstats(repo, stats)
688 if stats[3]:
688 if stats[3]:
689 repo.ui.status(_("use 'hg resolve' to retry unresolved "
689 repo.ui.status(_("use 'hg resolve' to retry unresolved "
690 "file merges\n"))
690 "file merges\n"))
691 return 1
691 return 1
692 finally:
692 finally:
693 ui.setconfig('ui', 'forcemerge', '', '')
693 ui.setconfig('ui', 'forcemerge', '', '')
694 lockmod.release(dsguard)
694 lockmod.release(dsguard)
695 else:
695 else:
696 hg.clean(repo, node, show_stats=False)
696 hg.clean(repo, node, show_stats=False)
697 repo.dirstate.setbranch(branch)
697 repo.dirstate.setbranch(branch)
698 cmdutil.revert(ui, repo, rctx, repo.dirstate.parents())
698 cmdutil.revert(ui, repo, rctx, repo.dirstate.parents())
699
699
700 if opts.get('no_commit'):
700 if opts.get('no_commit'):
701 msg = _("changeset %s backed out, "
701 msg = _("changeset %s backed out, "
702 "don't forget to commit.\n")
702 "don't forget to commit.\n")
703 ui.status(msg % short(node))
703 ui.status(msg % short(node))
704 return 0
704 return 0
705
705
706 def commitfunc(ui, repo, message, match, opts):
706 def commitfunc(ui, repo, message, match, opts):
707 editform = 'backout'
707 editform = 'backout'
708 e = cmdutil.getcommiteditor(editform=editform, **opts)
708 e = cmdutil.getcommiteditor(editform=editform, **opts)
709 if not message:
709 if not message:
710 # we don't translate commit messages
710 # we don't translate commit messages
711 message = "Backed out changeset %s" % short(node)
711 message = "Backed out changeset %s" % short(node)
712 e = cmdutil.getcommiteditor(edit=True, editform=editform)
712 e = cmdutil.getcommiteditor(edit=True, editform=editform)
713 return repo.commit(message, opts.get('user'), opts.get('date'),
713 return repo.commit(message, opts.get('user'), opts.get('date'),
714 match, editor=e)
714 match, editor=e)
715 newnode = cmdutil.commit(ui, repo, commitfunc, [], opts)
715 newnode = cmdutil.commit(ui, repo, commitfunc, [], opts)
716 if not newnode:
716 if not newnode:
717 ui.status(_("nothing changed\n"))
717 ui.status(_("nothing changed\n"))
718 return 1
718 return 1
719 cmdutil.commitstatus(repo, newnode, branch, bheads)
719 cmdutil.commitstatus(repo, newnode, branch, bheads)
720
720
721 def nice(node):
721 def nice(node):
722 return '%d:%s' % (repo.changelog.rev(node), short(node))
722 return '%d:%s' % (repo.changelog.rev(node), short(node))
723 ui.status(_('changeset %s backs out changeset %s\n') %
723 ui.status(_('changeset %s backs out changeset %s\n') %
724 (nice(repo.changelog.tip()), nice(node)))
724 (nice(repo.changelog.tip()), nice(node)))
725 if opts.get('merge') and op1 != node:
725 if opts.get('merge') and op1 != node:
726 hg.clean(repo, op1, show_stats=False)
726 hg.clean(repo, op1, show_stats=False)
727 ui.status(_('merging with changeset %s\n')
727 ui.status(_('merging with changeset %s\n')
728 % nice(repo.changelog.tip()))
728 % nice(repo.changelog.tip()))
729 try:
729 try:
730 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
730 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
731 'backout')
731 'backout')
732 return hg.merge(repo, hex(repo.changelog.tip()))
732 return hg.merge(repo, hex(repo.changelog.tip()))
733 finally:
733 finally:
734 ui.setconfig('ui', 'forcemerge', '', '')
734 ui.setconfig('ui', 'forcemerge', '', '')
735 return 0
735 return 0
736
736
737 @command('bisect',
737 @command('bisect',
738 [('r', 'reset', False, _('reset bisect state')),
738 [('r', 'reset', False, _('reset bisect state')),
739 ('g', 'good', False, _('mark changeset good')),
739 ('g', 'good', False, _('mark changeset good')),
740 ('b', 'bad', False, _('mark changeset bad')),
740 ('b', 'bad', False, _('mark changeset bad')),
741 ('s', 'skip', False, _('skip testing changeset')),
741 ('s', 'skip', False, _('skip testing changeset')),
742 ('e', 'extend', False, _('extend the bisect range')),
742 ('e', 'extend', False, _('extend the bisect range')),
743 ('c', 'command', '', _('use command to check changeset state'), _('CMD')),
743 ('c', 'command', '', _('use command to check changeset state'), _('CMD')),
744 ('U', 'noupdate', False, _('do not update to target'))],
744 ('U', 'noupdate', False, _('do not update to target'))],
745 _("[-gbsr] [-U] [-c CMD] [REV]"))
745 _("[-gbsr] [-U] [-c CMD] [REV]"))
746 def bisect(ui, repo, rev=None, extra=None, command=None,
746 def bisect(ui, repo, rev=None, extra=None, command=None,
747 reset=None, good=None, bad=None, skip=None, extend=None,
747 reset=None, good=None, bad=None, skip=None, extend=None,
748 noupdate=None):
748 noupdate=None):
749 """subdivision search of changesets
749 """subdivision search of changesets
750
750
751 This command helps to find changesets which introduce problems. To
751 This command helps to find changesets which introduce problems. To
752 use, mark the earliest changeset you know exhibits the problem as
752 use, mark the earliest changeset you know exhibits the problem as
753 bad, then mark the latest changeset which is free from the problem
753 bad, then mark the latest changeset which is free from the problem
754 as good. Bisect will update your working directory to a revision
754 as good. Bisect will update your working directory to a revision
755 for testing (unless the -U/--noupdate option is specified). Once
755 for testing (unless the -U/--noupdate option is specified). Once
756 you have performed tests, mark the working directory as good or
756 you have performed tests, mark the working directory as good or
757 bad, and bisect will either update to another candidate changeset
757 bad, and bisect will either update to another candidate changeset
758 or announce that it has found the bad revision.
758 or announce that it has found the bad revision.
759
759
760 As a shortcut, you can also use the revision argument to mark a
760 As a shortcut, you can also use the revision argument to mark a
761 revision as good or bad without checking it out first.
761 revision as good or bad without checking it out first.
762
762
763 If you supply a command, it will be used for automatic bisection.
763 If you supply a command, it will be used for automatic bisection.
764 The environment variable HG_NODE will contain the ID of the
764 The environment variable HG_NODE will contain the ID of the
765 changeset being tested. The exit status of the command will be
765 changeset being tested. The exit status of the command will be
766 used to mark revisions as good or bad: status 0 means good, 125
766 used to mark revisions as good or bad: status 0 means good, 125
767 means to skip the revision, 127 (command not found) will abort the
767 means to skip the revision, 127 (command not found) will abort the
768 bisection, and any other non-zero exit status means the revision
768 bisection, and any other non-zero exit status means the revision
769 is bad.
769 is bad.
770
770
771 .. container:: verbose
771 .. container:: verbose
772
772
773 Some examples:
773 Some examples:
774
774
775 - start a bisection with known bad revision 34, and good revision 12::
775 - start a bisection with known bad revision 34, and good revision 12::
776
776
777 hg bisect --bad 34
777 hg bisect --bad 34
778 hg bisect --good 12
778 hg bisect --good 12
779
779
780 - advance the current bisection by marking current revision as good or
780 - advance the current bisection by marking current revision as good or
781 bad::
781 bad::
782
782
783 hg bisect --good
783 hg bisect --good
784 hg bisect --bad
784 hg bisect --bad
785
785
786 - mark the current revision, or a known revision, to be skipped (e.g. if
786 - mark the current revision, or a known revision, to be skipped (e.g. if
787 that revision is not usable because of another issue)::
787 that revision is not usable because of another issue)::
788
788
789 hg bisect --skip
789 hg bisect --skip
790 hg bisect --skip 23
790 hg bisect --skip 23
791
791
792 - skip all revisions that do not touch directories ``foo`` or ``bar``::
792 - skip all revisions that do not touch directories ``foo`` or ``bar``::
793
793
794 hg bisect --skip "!( file('path:foo') & file('path:bar') )"
794 hg bisect --skip "!( file('path:foo') & file('path:bar') )"
795
795
796 - forget the current bisection::
796 - forget the current bisection::
797
797
798 hg bisect --reset
798 hg bisect --reset
799
799
800 - use 'make && make tests' to automatically find the first broken
800 - use 'make && make tests' to automatically find the first broken
801 revision::
801 revision::
802
802
803 hg bisect --reset
803 hg bisect --reset
804 hg bisect --bad 34
804 hg bisect --bad 34
805 hg bisect --good 12
805 hg bisect --good 12
806 hg bisect --command "make && make tests"
806 hg bisect --command "make && make tests"
807
807
808 - see all changesets whose states are already known in the current
808 - see all changesets whose states are already known in the current
809 bisection::
809 bisection::
810
810
811 hg log -r "bisect(pruned)"
811 hg log -r "bisect(pruned)"
812
812
813 - see the changeset currently being bisected (especially useful
813 - see the changeset currently being bisected (especially useful
814 if running with -U/--noupdate)::
814 if running with -U/--noupdate)::
815
815
816 hg log -r "bisect(current)"
816 hg log -r "bisect(current)"
817
817
818 - see all changesets that took part in the current bisection::
818 - see all changesets that took part in the current bisection::
819
819
820 hg log -r "bisect(range)"
820 hg log -r "bisect(range)"
821
821
822 - you can even get a nice graph::
822 - you can even get a nice graph::
823
823
824 hg log --graph -r "bisect(range)"
824 hg log --graph -r "bisect(range)"
825
825
826 See :hg:`help revisions.bisect` for more about the `bisect()` predicate.
826 See :hg:`help revisions.bisect` for more about the `bisect()` predicate.
827
827
828 Returns 0 on success.
828 Returns 0 on success.
829 """
829 """
830 # backward compatibility
830 # backward compatibility
831 if rev in "good bad reset init".split():
831 if rev in "good bad reset init".split():
832 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
832 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
833 cmd, rev, extra = rev, extra, None
833 cmd, rev, extra = rev, extra, None
834 if cmd == "good":
834 if cmd == "good":
835 good = True
835 good = True
836 elif cmd == "bad":
836 elif cmd == "bad":
837 bad = True
837 bad = True
838 else:
838 else:
839 reset = True
839 reset = True
840 elif extra or good + bad + skip + reset + extend + bool(command) > 1:
840 elif extra or good + bad + skip + reset + extend + bool(command) > 1:
841 raise error.Abort(_('incompatible arguments'))
841 raise error.Abort(_('incompatible arguments'))
842
842
843 cmdutil.checkunfinished(repo)
843 cmdutil.checkunfinished(repo)
844
844
845 if reset:
845 if reset:
846 hbisect.resetstate(repo)
846 hbisect.resetstate(repo)
847 return
847 return
848
848
849 state = hbisect.load_state(repo)
849 state = hbisect.load_state(repo)
850
850
851 # update state
851 # update state
852 if good or bad or skip:
852 if good or bad or skip:
853 if rev:
853 if rev:
854 nodes = [repo.lookup(i) for i in scmutil.revrange(repo, [rev])]
854 nodes = [repo.lookup(i) for i in scmutil.revrange(repo, [rev])]
855 else:
855 else:
856 nodes = [repo.lookup('.')]
856 nodes = [repo.lookup('.')]
857 if good:
857 if good:
858 state['good'] += nodes
858 state['good'] += nodes
859 elif bad:
859 elif bad:
860 state['bad'] += nodes
860 state['bad'] += nodes
861 elif skip:
861 elif skip:
862 state['skip'] += nodes
862 state['skip'] += nodes
863 hbisect.save_state(repo, state)
863 hbisect.save_state(repo, state)
864 if not (state['good'] and state['bad']):
864 if not (state['good'] and state['bad']):
865 return
865 return
866
866
867 def mayupdate(repo, node, show_stats=True):
867 def mayupdate(repo, node, show_stats=True):
868 """common used update sequence"""
868 """common used update sequence"""
869 if noupdate:
869 if noupdate:
870 return
870 return
871 cmdutil.bailifchanged(repo)
871 cmdutil.bailifchanged(repo)
872 return hg.clean(repo, node, show_stats=show_stats)
872 return hg.clean(repo, node, show_stats=show_stats)
873
873
874 displayer = cmdutil.show_changeset(ui, repo, {})
874 displayer = cmdutil.show_changeset(ui, repo, {})
875
875
876 if command:
876 if command:
877 changesets = 1
877 changesets = 1
878 if noupdate:
878 if noupdate:
879 try:
879 try:
880 node = state['current'][0]
880 node = state['current'][0]
881 except LookupError:
881 except LookupError:
882 raise error.Abort(_('current bisect revision is unknown - '
882 raise error.Abort(_('current bisect revision is unknown - '
883 'start a new bisect to fix'))
883 'start a new bisect to fix'))
884 else:
884 else:
885 node, p2 = repo.dirstate.parents()
885 node, p2 = repo.dirstate.parents()
886 if p2 != nullid:
886 if p2 != nullid:
887 raise error.Abort(_('current bisect revision is a merge'))
887 raise error.Abort(_('current bisect revision is a merge'))
888 if rev:
888 if rev:
889 node = repo[scmutil.revsingle(repo, rev, node)].node()
889 node = repo[scmutil.revsingle(repo, rev, node)].node()
890 try:
890 try:
891 while changesets:
891 while changesets:
892 # update state
892 # update state
893 state['current'] = [node]
893 state['current'] = [node]
894 hbisect.save_state(repo, state)
894 hbisect.save_state(repo, state)
895 status = ui.system(command, environ={'HG_NODE': hex(node)})
895 status = ui.system(command, environ={'HG_NODE': hex(node)})
896 if status == 125:
896 if status == 125:
897 transition = "skip"
897 transition = "skip"
898 elif status == 0:
898 elif status == 0:
899 transition = "good"
899 transition = "good"
900 # status < 0 means process was killed
900 # status < 0 means process was killed
901 elif status == 127:
901 elif status == 127:
902 raise error.Abort(_("failed to execute %s") % command)
902 raise error.Abort(_("failed to execute %s") % command)
903 elif status < 0:
903 elif status < 0:
904 raise error.Abort(_("%s killed") % command)
904 raise error.Abort(_("%s killed") % command)
905 else:
905 else:
906 transition = "bad"
906 transition = "bad"
907 state[transition].append(node)
907 state[transition].append(node)
908 ctx = repo[node]
908 ctx = repo[node]
909 ui.status(_('changeset %d:%s: %s\n') % (ctx, ctx, transition))
909 ui.status(_('changeset %d:%s: %s\n') % (ctx, ctx, transition))
910 hbisect.checkstate(state)
910 hbisect.checkstate(state)
911 # bisect
911 # bisect
912 nodes, changesets, bgood = hbisect.bisect(repo.changelog, state)
912 nodes, changesets, bgood = hbisect.bisect(repo.changelog, state)
913 # update to next check
913 # update to next check
914 node = nodes[0]
914 node = nodes[0]
915 mayupdate(repo, node, show_stats=False)
915 mayupdate(repo, node, show_stats=False)
916 finally:
916 finally:
917 state['current'] = [node]
917 state['current'] = [node]
918 hbisect.save_state(repo, state)
918 hbisect.save_state(repo, state)
919 hbisect.printresult(ui, repo, state, displayer, nodes, bgood)
919 hbisect.printresult(ui, repo, state, displayer, nodes, bgood)
920 return
920 return
921
921
922 hbisect.checkstate(state)
922 hbisect.checkstate(state)
923
923
924 # actually bisect
924 # actually bisect
925 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
925 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
926 if extend:
926 if extend:
927 if not changesets:
927 if not changesets:
928 extendnode = hbisect.extendrange(repo, state, nodes, good)
928 extendnode = hbisect.extendrange(repo, state, nodes, good)
929 if extendnode is not None:
929 if extendnode is not None:
930 ui.write(_("Extending search to changeset %d:%s\n")
930 ui.write(_("Extending search to changeset %d:%s\n")
931 % (extendnode.rev(), extendnode))
931 % (extendnode.rev(), extendnode))
932 state['current'] = [extendnode.node()]
932 state['current'] = [extendnode.node()]
933 hbisect.save_state(repo, state)
933 hbisect.save_state(repo, state)
934 return mayupdate(repo, extendnode.node())
934 return mayupdate(repo, extendnode.node())
935 raise error.Abort(_("nothing to extend"))
935 raise error.Abort(_("nothing to extend"))
936
936
937 if changesets == 0:
937 if changesets == 0:
938 hbisect.printresult(ui, repo, state, displayer, nodes, good)
938 hbisect.printresult(ui, repo, state, displayer, nodes, good)
939 else:
939 else:
940 assert len(nodes) == 1 # only a single node can be tested next
940 assert len(nodes) == 1 # only a single node can be tested next
941 node = nodes[0]
941 node = nodes[0]
942 # compute the approximate number of remaining tests
942 # compute the approximate number of remaining tests
943 tests, size = 0, 2
943 tests, size = 0, 2
944 while size <= changesets:
944 while size <= changesets:
945 tests, size = tests + 1, size * 2
945 tests, size = tests + 1, size * 2
946 rev = repo.changelog.rev(node)
946 rev = repo.changelog.rev(node)
947 ui.write(_("Testing changeset %d:%s "
947 ui.write(_("Testing changeset %d:%s "
948 "(%d changesets remaining, ~%d tests)\n")
948 "(%d changesets remaining, ~%d tests)\n")
949 % (rev, short(node), changesets, tests))
949 % (rev, short(node), changesets, tests))
950 state['current'] = [node]
950 state['current'] = [node]
951 hbisect.save_state(repo, state)
951 hbisect.save_state(repo, state)
952 return mayupdate(repo, node)
952 return mayupdate(repo, node)
953
953
954 @command('bookmarks|bookmark',
954 @command('bookmarks|bookmark',
955 [('f', 'force', False, _('force')),
955 [('f', 'force', False, _('force')),
956 ('r', 'rev', '', _('revision for bookmark action'), _('REV')),
956 ('r', 'rev', '', _('revision for bookmark action'), _('REV')),
957 ('d', 'delete', False, _('delete a given bookmark')),
957 ('d', 'delete', False, _('delete a given bookmark')),
958 ('m', 'rename', '', _('rename a given bookmark'), _('OLD')),
958 ('m', 'rename', '', _('rename a given bookmark'), _('OLD')),
959 ('i', 'inactive', False, _('mark a bookmark inactive')),
959 ('i', 'inactive', False, _('mark a bookmark inactive')),
960 ] + formatteropts,
960 ] + formatteropts,
961 _('hg bookmarks [OPTIONS]... [NAME]...'))
961 _('hg bookmarks [OPTIONS]... [NAME]...'))
962 def bookmark(ui, repo, *names, **opts):
962 def bookmark(ui, repo, *names, **opts):
963 '''create a new bookmark or list existing bookmarks
963 '''create a new bookmark or list existing bookmarks
964
964
965 Bookmarks are labels on changesets to help track lines of development.
965 Bookmarks are labels on changesets to help track lines of development.
966 Bookmarks are unversioned and can be moved, renamed and deleted.
966 Bookmarks are unversioned and can be moved, renamed and deleted.
967 Deleting or moving a bookmark has no effect on the associated changesets.
967 Deleting or moving a bookmark has no effect on the associated changesets.
968
968
969 Creating or updating to a bookmark causes it to be marked as 'active'.
969 Creating or updating to a bookmark causes it to be marked as 'active'.
970 The active bookmark is indicated with a '*'.
970 The active bookmark is indicated with a '*'.
971 When a commit is made, the active bookmark will advance to the new commit.
971 When a commit is made, the active bookmark will advance to the new commit.
972 A plain :hg:`update` will also advance an active bookmark, if possible.
972 A plain :hg:`update` will also advance an active bookmark, if possible.
973 Updating away from a bookmark will cause it to be deactivated.
973 Updating away from a bookmark will cause it to be deactivated.
974
974
975 Bookmarks can be pushed and pulled between repositories (see
975 Bookmarks can be pushed and pulled between repositories (see
976 :hg:`help push` and :hg:`help pull`). If a shared bookmark has
976 :hg:`help push` and :hg:`help pull`). If a shared bookmark has
977 diverged, a new 'divergent bookmark' of the form 'name@path' will
977 diverged, a new 'divergent bookmark' of the form 'name@path' will
978 be created. Using :hg:`merge` will resolve the divergence.
978 be created. Using :hg:`merge` will resolve the divergence.
979
979
980 A bookmark named '@' has the special property that :hg:`clone` will
980 A bookmark named '@' has the special property that :hg:`clone` will
981 check it out by default if it exists.
981 check it out by default if it exists.
982
982
983 .. container:: verbose
983 .. container:: verbose
984
984
985 Examples:
985 Examples:
986
986
987 - create an active bookmark for a new line of development::
987 - create an active bookmark for a new line of development::
988
988
989 hg book new-feature
989 hg book new-feature
990
990
991 - create an inactive bookmark as a place marker::
991 - create an inactive bookmark as a place marker::
992
992
993 hg book -i reviewed
993 hg book -i reviewed
994
994
995 - create an inactive bookmark on another changeset::
995 - create an inactive bookmark on another changeset::
996
996
997 hg book -r .^ tested
997 hg book -r .^ tested
998
998
999 - rename bookmark turkey to dinner::
999 - rename bookmark turkey to dinner::
1000
1000
1001 hg book -m turkey dinner
1001 hg book -m turkey dinner
1002
1002
1003 - move the '@' bookmark from another branch::
1003 - move the '@' bookmark from another branch::
1004
1004
1005 hg book -f @
1005 hg book -f @
1006 '''
1006 '''
1007 force = opts.get('force')
1007 force = opts.get('force')
1008 rev = opts.get('rev')
1008 rev = opts.get('rev')
1009 delete = opts.get('delete')
1009 delete = opts.get('delete')
1010 rename = opts.get('rename')
1010 rename = opts.get('rename')
1011 inactive = opts.get('inactive')
1011 inactive = opts.get('inactive')
1012
1012
1013 def checkformat(mark):
1013 def checkformat(mark):
1014 mark = mark.strip()
1014 mark = mark.strip()
1015 if not mark:
1015 if not mark:
1016 raise error.Abort(_("bookmark names cannot consist entirely of "
1016 raise error.Abort(_("bookmark names cannot consist entirely of "
1017 "whitespace"))
1017 "whitespace"))
1018 scmutil.checknewlabel(repo, mark, 'bookmark')
1018 scmutil.checknewlabel(repo, mark, 'bookmark')
1019 return mark
1019 return mark
1020
1020
1021 def checkconflict(repo, mark, cur, force=False, target=None):
1021 def checkconflict(repo, mark, cur, force=False, target=None):
1022 if mark in marks and not force:
1022 if mark in marks and not force:
1023 if target:
1023 if target:
1024 if marks[mark] == target and target == cur:
1024 if marks[mark] == target and target == cur:
1025 # re-activating a bookmark
1025 # re-activating a bookmark
1026 return
1026 return
1027 anc = repo.changelog.ancestors([repo[target].rev()])
1027 anc = repo.changelog.ancestors([repo[target].rev()])
1028 bmctx = repo[marks[mark]]
1028 bmctx = repo[marks[mark]]
1029 divs = [repo[b].node() for b in marks
1029 divs = [repo[b].node() for b in marks
1030 if b.split('@', 1)[0] == mark.split('@', 1)[0]]
1030 if b.split('@', 1)[0] == mark.split('@', 1)[0]]
1031
1031
1032 # allow resolving a single divergent bookmark even if moving
1032 # allow resolving a single divergent bookmark even if moving
1033 # the bookmark across branches when a revision is specified
1033 # the bookmark across branches when a revision is specified
1034 # that contains a divergent bookmark
1034 # that contains a divergent bookmark
1035 if bmctx.rev() not in anc and target in divs:
1035 if bmctx.rev() not in anc and target in divs:
1036 bookmarks.deletedivergent(repo, [target], mark)
1036 bookmarks.deletedivergent(repo, [target], mark)
1037 return
1037 return
1038
1038
1039 deletefrom = [b for b in divs
1039 deletefrom = [b for b in divs
1040 if repo[b].rev() in anc or b == target]
1040 if repo[b].rev() in anc or b == target]
1041 bookmarks.deletedivergent(repo, deletefrom, mark)
1041 bookmarks.deletedivergent(repo, deletefrom, mark)
1042 if bookmarks.validdest(repo, bmctx, repo[target]):
1042 if bookmarks.validdest(repo, bmctx, repo[target]):
1043 ui.status(_("moving bookmark '%s' forward from %s\n") %
1043 ui.status(_("moving bookmark '%s' forward from %s\n") %
1044 (mark, short(bmctx.node())))
1044 (mark, short(bmctx.node())))
1045 return
1045 return
1046 raise error.Abort(_("bookmark '%s' already exists "
1046 raise error.Abort(_("bookmark '%s' already exists "
1047 "(use -f to force)") % mark)
1047 "(use -f to force)") % mark)
1048 if ((mark in repo.branchmap() or mark == repo.dirstate.branch())
1048 if ((mark in repo.branchmap() or mark == repo.dirstate.branch())
1049 and not force):
1049 and not force):
1050 raise error.Abort(
1050 raise error.Abort(
1051 _("a bookmark cannot have the name of an existing branch"))
1051 _("a bookmark cannot have the name of an existing branch"))
1052
1052
1053 if delete and rename:
1053 if delete and rename:
1054 raise error.Abort(_("--delete and --rename are incompatible"))
1054 raise error.Abort(_("--delete and --rename are incompatible"))
1055 if delete and rev:
1055 if delete and rev:
1056 raise error.Abort(_("--rev is incompatible with --delete"))
1056 raise error.Abort(_("--rev is incompatible with --delete"))
1057 if rename and rev:
1057 if rename and rev:
1058 raise error.Abort(_("--rev is incompatible with --rename"))
1058 raise error.Abort(_("--rev is incompatible with --rename"))
1059 if not names and (delete or rev):
1059 if not names and (delete or rev):
1060 raise error.Abort(_("bookmark name required"))
1060 raise error.Abort(_("bookmark name required"))
1061
1061
1062 if delete or rename or names or inactive:
1062 if delete or rename or names or inactive:
1063 wlock = lock = tr = None
1063 wlock = lock = tr = None
1064 try:
1064 try:
1065 wlock = repo.wlock()
1065 wlock = repo.wlock()
1066 lock = repo.lock()
1066 lock = repo.lock()
1067 cur = repo.changectx('.').node()
1067 cur = repo.changectx('.').node()
1068 marks = repo._bookmarks
1068 marks = repo._bookmarks
1069 if delete:
1069 if delete:
1070 tr = repo.transaction('bookmark')
1070 tr = repo.transaction('bookmark')
1071 for mark in names:
1071 for mark in names:
1072 if mark not in marks:
1072 if mark not in marks:
1073 raise error.Abort(_("bookmark '%s' does not exist") %
1073 raise error.Abort(_("bookmark '%s' does not exist") %
1074 mark)
1074 mark)
1075 if mark == repo._activebookmark:
1075 if mark == repo._activebookmark:
1076 bookmarks.deactivate(repo)
1076 bookmarks.deactivate(repo)
1077 del marks[mark]
1077 del marks[mark]
1078
1078
1079 elif rename:
1079 elif rename:
1080 tr = repo.transaction('bookmark')
1080 tr = repo.transaction('bookmark')
1081 if not names:
1081 if not names:
1082 raise error.Abort(_("new bookmark name required"))
1082 raise error.Abort(_("new bookmark name required"))
1083 elif len(names) > 1:
1083 elif len(names) > 1:
1084 raise error.Abort(_("only one new bookmark name allowed"))
1084 raise error.Abort(_("only one new bookmark name allowed"))
1085 mark = checkformat(names[0])
1085 mark = checkformat(names[0])
1086 if rename not in marks:
1086 if rename not in marks:
1087 raise error.Abort(_("bookmark '%s' does not exist")
1087 raise error.Abort(_("bookmark '%s' does not exist")
1088 % rename)
1088 % rename)
1089 checkconflict(repo, mark, cur, force)
1089 checkconflict(repo, mark, cur, force)
1090 marks[mark] = marks[rename]
1090 marks[mark] = marks[rename]
1091 if repo._activebookmark == rename and not inactive:
1091 if repo._activebookmark == rename and not inactive:
1092 bookmarks.activate(repo, mark)
1092 bookmarks.activate(repo, mark)
1093 del marks[rename]
1093 del marks[rename]
1094 elif names:
1094 elif names:
1095 tr = repo.transaction('bookmark')
1095 tr = repo.transaction('bookmark')
1096 newact = None
1096 newact = None
1097 for mark in names:
1097 for mark in names:
1098 mark = checkformat(mark)
1098 mark = checkformat(mark)
1099 if newact is None:
1099 if newact is None:
1100 newact = mark
1100 newact = mark
1101 if inactive and mark == repo._activebookmark:
1101 if inactive and mark == repo._activebookmark:
1102 bookmarks.deactivate(repo)
1102 bookmarks.deactivate(repo)
1103 return
1103 return
1104 tgt = cur
1104 tgt = cur
1105 if rev:
1105 if rev:
1106 tgt = scmutil.revsingle(repo, rev).node()
1106 tgt = scmutil.revsingle(repo, rev).node()
1107 checkconflict(repo, mark, cur, force, tgt)
1107 checkconflict(repo, mark, cur, force, tgt)
1108 marks[mark] = tgt
1108 marks[mark] = tgt
1109 if not inactive and cur == marks[newact] and not rev:
1109 if not inactive and cur == marks[newact] and not rev:
1110 bookmarks.activate(repo, newact)
1110 bookmarks.activate(repo, newact)
1111 elif cur != tgt and newact == repo._activebookmark:
1111 elif cur != tgt and newact == repo._activebookmark:
1112 bookmarks.deactivate(repo)
1112 bookmarks.deactivate(repo)
1113 elif inactive:
1113 elif inactive:
1114 if len(marks) == 0:
1114 if len(marks) == 0:
1115 ui.status(_("no bookmarks set\n"))
1115 ui.status(_("no bookmarks set\n"))
1116 elif not repo._activebookmark:
1116 elif not repo._activebookmark:
1117 ui.status(_("no active bookmark\n"))
1117 ui.status(_("no active bookmark\n"))
1118 else:
1118 else:
1119 bookmarks.deactivate(repo)
1119 bookmarks.deactivate(repo)
1120 if tr is not None:
1120 if tr is not None:
1121 marks.recordchange(tr)
1121 marks.recordchange(tr)
1122 tr.close()
1122 tr.close()
1123 finally:
1123 finally:
1124 lockmod.release(tr, lock, wlock)
1124 lockmod.release(tr, lock, wlock)
1125 else: # show bookmarks
1125 else: # show bookmarks
1126 fm = ui.formatter('bookmarks', opts)
1126 fm = ui.formatter('bookmarks', opts)
1127 hexfn = fm.hexfunc
1127 hexfn = fm.hexfunc
1128 marks = repo._bookmarks
1128 marks = repo._bookmarks
1129 if len(marks) == 0 and fm.isplain():
1129 if len(marks) == 0 and fm.isplain():
1130 ui.status(_("no bookmarks set\n"))
1130 ui.status(_("no bookmarks set\n"))
1131 for bmark, n in sorted(marks.iteritems()):
1131 for bmark, n in sorted(marks.iteritems()):
1132 active = repo._activebookmark
1132 active = repo._activebookmark
1133 if bmark == active:
1133 if bmark == active:
1134 prefix, label = '*', activebookmarklabel
1134 prefix, label = '*', activebookmarklabel
1135 else:
1135 else:
1136 prefix, label = ' ', ''
1136 prefix, label = ' ', ''
1137
1137
1138 fm.startitem()
1138 fm.startitem()
1139 if not ui.quiet:
1139 if not ui.quiet:
1140 fm.plain(' %s ' % prefix, label=label)
1140 fm.plain(' %s ' % prefix, label=label)
1141 fm.write('bookmark', '%s', bmark, label=label)
1141 fm.write('bookmark', '%s', bmark, label=label)
1142 pad = " " * (25 - encoding.colwidth(bmark))
1142 pad = " " * (25 - encoding.colwidth(bmark))
1143 fm.condwrite(not ui.quiet, 'rev node', pad + ' %d:%s',
1143 fm.condwrite(not ui.quiet, 'rev node', pad + ' %d:%s',
1144 repo.changelog.rev(n), hexfn(n), label=label)
1144 repo.changelog.rev(n), hexfn(n), label=label)
1145 fm.data(active=(bmark == active))
1145 fm.data(active=(bmark == active))
1146 fm.plain('\n')
1146 fm.plain('\n')
1147 fm.end()
1147 fm.end()
1148
1148
1149 @command('branch',
1149 @command('branch',
1150 [('f', 'force', None,
1150 [('f', 'force', None,
1151 _('set branch name even if it shadows an existing branch')),
1151 _('set branch name even if it shadows an existing branch')),
1152 ('C', 'clean', None, _('reset branch name to parent branch name'))],
1152 ('C', 'clean', None, _('reset branch name to parent branch name'))],
1153 _('[-fC] [NAME]'))
1153 _('[-fC] [NAME]'))
1154 def branch(ui, repo, label=None, **opts):
1154 def branch(ui, repo, label=None, **opts):
1155 """set or show the current branch name
1155 """set or show the current branch name
1156
1156
1157 .. note::
1157 .. note::
1158
1158
1159 Branch names are permanent and global. Use :hg:`bookmark` to create a
1159 Branch names are permanent and global. Use :hg:`bookmark` to create a
1160 light-weight bookmark instead. See :hg:`help glossary` for more
1160 light-weight bookmark instead. See :hg:`help glossary` for more
1161 information about named branches and bookmarks.
1161 information about named branches and bookmarks.
1162
1162
1163 With no argument, show the current branch name. With one argument,
1163 With no argument, show the current branch name. With one argument,
1164 set the working directory branch name (the branch will not exist
1164 set the working directory branch name (the branch will not exist
1165 in the repository until the next commit). Standard practice
1165 in the repository until the next commit). Standard practice
1166 recommends that primary development take place on the 'default'
1166 recommends that primary development take place on the 'default'
1167 branch.
1167 branch.
1168
1168
1169 Unless -f/--force is specified, branch will not let you set a
1169 Unless -f/--force is specified, branch will not let you set a
1170 branch name that already exists.
1170 branch name that already exists.
1171
1171
1172 Use -C/--clean to reset the working directory branch to that of
1172 Use -C/--clean to reset the working directory branch to that of
1173 the parent of the working directory, negating a previous branch
1173 the parent of the working directory, negating a previous branch
1174 change.
1174 change.
1175
1175
1176 Use the command :hg:`update` to switch to an existing branch. Use
1176 Use the command :hg:`update` to switch to an existing branch. Use
1177 :hg:`commit --close-branch` to mark this branch head as closed.
1177 :hg:`commit --close-branch` to mark this branch head as closed.
1178 When all heads of a branch are closed, the branch will be
1178 When all heads of a branch are closed, the branch will be
1179 considered closed.
1179 considered closed.
1180
1180
1181 Returns 0 on success.
1181 Returns 0 on success.
1182 """
1182 """
1183 if label:
1183 if label:
1184 label = label.strip()
1184 label = label.strip()
1185
1185
1186 if not opts.get('clean') and not label:
1186 if not opts.get('clean') and not label:
1187 ui.write("%s\n" % repo.dirstate.branch())
1187 ui.write("%s\n" % repo.dirstate.branch())
1188 return
1188 return
1189
1189
1190 with repo.wlock():
1190 with repo.wlock():
1191 if opts.get('clean'):
1191 if opts.get('clean'):
1192 label = repo[None].p1().branch()
1192 label = repo[None].p1().branch()
1193 repo.dirstate.setbranch(label)
1193 repo.dirstate.setbranch(label)
1194 ui.status(_('reset working directory to branch %s\n') % label)
1194 ui.status(_('reset working directory to branch %s\n') % label)
1195 elif label:
1195 elif label:
1196 if not opts.get('force') and label in repo.branchmap():
1196 if not opts.get('force') and label in repo.branchmap():
1197 if label not in [p.branch() for p in repo[None].parents()]:
1197 if label not in [p.branch() for p in repo[None].parents()]:
1198 raise error.Abort(_('a branch of the same name already'
1198 raise error.Abort(_('a branch of the same name already'
1199 ' exists'),
1199 ' exists'),
1200 # i18n: "it" refers to an existing branch
1200 # i18n: "it" refers to an existing branch
1201 hint=_("use 'hg update' to switch to it"))
1201 hint=_("use 'hg update' to switch to it"))
1202 scmutil.checknewlabel(repo, label, 'branch')
1202 scmutil.checknewlabel(repo, label, 'branch')
1203 repo.dirstate.setbranch(label)
1203 repo.dirstate.setbranch(label)
1204 ui.status(_('marked working directory as branch %s\n') % label)
1204 ui.status(_('marked working directory as branch %s\n') % label)
1205
1205
1206 # find any open named branches aside from default
1206 # find any open named branches aside from default
1207 others = [n for n, h, t, c in repo.branchmap().iterbranches()
1207 others = [n for n, h, t, c in repo.branchmap().iterbranches()
1208 if n != "default" and not c]
1208 if n != "default" and not c]
1209 if not others:
1209 if not others:
1210 ui.status(_('(branches are permanent and global, '
1210 ui.status(_('(branches are permanent and global, '
1211 'did you want a bookmark?)\n'))
1211 'did you want a bookmark?)\n'))
1212
1212
1213 @command('branches',
1213 @command('branches',
1214 [('a', 'active', False,
1214 [('a', 'active', False,
1215 _('show only branches that have unmerged heads (DEPRECATED)')),
1215 _('show only branches that have unmerged heads (DEPRECATED)')),
1216 ('c', 'closed', False, _('show normal and closed branches')),
1216 ('c', 'closed', False, _('show normal and closed branches')),
1217 ] + formatteropts,
1217 ] + formatteropts,
1218 _('[-c]'))
1218 _('[-c]'))
1219 def branches(ui, repo, active=False, closed=False, **opts):
1219 def branches(ui, repo, active=False, closed=False, **opts):
1220 """list repository named branches
1220 """list repository named branches
1221
1221
1222 List the repository's named branches, indicating which ones are
1222 List the repository's named branches, indicating which ones are
1223 inactive. If -c/--closed is specified, also list branches which have
1223 inactive. If -c/--closed is specified, also list branches which have
1224 been marked closed (see :hg:`commit --close-branch`).
1224 been marked closed (see :hg:`commit --close-branch`).
1225
1225
1226 Use the command :hg:`update` to switch to an existing branch.
1226 Use the command :hg:`update` to switch to an existing branch.
1227
1227
1228 Returns 0.
1228 Returns 0.
1229 """
1229 """
1230
1230
1231 fm = ui.formatter('branches', opts)
1231 fm = ui.formatter('branches', opts)
1232 hexfunc = fm.hexfunc
1232 hexfunc = fm.hexfunc
1233
1233
1234 allheads = set(repo.heads())
1234 allheads = set(repo.heads())
1235 branches = []
1235 branches = []
1236 for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
1236 for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
1237 isactive = not isclosed and bool(set(heads) & allheads)
1237 isactive = not isclosed and bool(set(heads) & allheads)
1238 branches.append((tag, repo[tip], isactive, not isclosed))
1238 branches.append((tag, repo[tip], isactive, not isclosed))
1239 branches.sort(key=lambda i: (i[2], i[1].rev(), i[0], i[3]),
1239 branches.sort(key=lambda i: (i[2], i[1].rev(), i[0], i[3]),
1240 reverse=True)
1240 reverse=True)
1241
1241
1242 for tag, ctx, isactive, isopen in branches:
1242 for tag, ctx, isactive, isopen in branches:
1243 if active and not isactive:
1243 if active and not isactive:
1244 continue
1244 continue
1245 if isactive:
1245 if isactive:
1246 label = 'branches.active'
1246 label = 'branches.active'
1247 notice = ''
1247 notice = ''
1248 elif not isopen:
1248 elif not isopen:
1249 if not closed:
1249 if not closed:
1250 continue
1250 continue
1251 label = 'branches.closed'
1251 label = 'branches.closed'
1252 notice = _(' (closed)')
1252 notice = _(' (closed)')
1253 else:
1253 else:
1254 label = 'branches.inactive'
1254 label = 'branches.inactive'
1255 notice = _(' (inactive)')
1255 notice = _(' (inactive)')
1256 current = (tag == repo.dirstate.branch())
1256 current = (tag == repo.dirstate.branch())
1257 if current:
1257 if current:
1258 label = 'branches.current'
1258 label = 'branches.current'
1259
1259
1260 fm.startitem()
1260 fm.startitem()
1261 fm.write('branch', '%s', tag, label=label)
1261 fm.write('branch', '%s', tag, label=label)
1262 rev = ctx.rev()
1262 rev = ctx.rev()
1263 padsize = max(31 - len(str(rev)) - encoding.colwidth(tag), 0)
1263 padsize = max(31 - len(str(rev)) - encoding.colwidth(tag), 0)
1264 fmt = ' ' * padsize + ' %d:%s'
1264 fmt = ' ' * padsize + ' %d:%s'
1265 fm.condwrite(not ui.quiet, 'rev node', fmt, rev, hexfunc(ctx.node()),
1265 fm.condwrite(not ui.quiet, 'rev node', fmt, rev, hexfunc(ctx.node()),
1266 label='log.changeset changeset.%s' % ctx.phasestr())
1266 label='log.changeset changeset.%s' % ctx.phasestr())
1267 fm.data(active=isactive, closed=not isopen, current=current)
1267 fm.data(active=isactive, closed=not isopen, current=current)
1268 if not ui.quiet:
1268 if not ui.quiet:
1269 fm.plain(notice)
1269 fm.plain(notice)
1270 fm.plain('\n')
1270 fm.plain('\n')
1271 fm.end()
1271 fm.end()
1272
1272
1273 @command('bundle',
1273 @command('bundle',
1274 [('f', 'force', None, _('run even when the destination is unrelated')),
1274 [('f', 'force', None, _('run even when the destination is unrelated')),
1275 ('r', 'rev', [], _('a changeset intended to be added to the destination'),
1275 ('r', 'rev', [], _('a changeset intended to be added to the destination'),
1276 _('REV')),
1276 _('REV')),
1277 ('b', 'branch', [], _('a specific branch you would like to bundle'),
1277 ('b', 'branch', [], _('a specific branch you would like to bundle'),
1278 _('BRANCH')),
1278 _('BRANCH')),
1279 ('', 'base', [],
1279 ('', 'base', [],
1280 _('a base changeset assumed to be available at the destination'),
1280 _('a base changeset assumed to be available at the destination'),
1281 _('REV')),
1281 _('REV')),
1282 ('a', 'all', None, _('bundle all changesets in the repository')),
1282 ('a', 'all', None, _('bundle all changesets in the repository')),
1283 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
1283 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
1284 ] + remoteopts,
1284 ] + remoteopts,
1285 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]'))
1285 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]'))
1286 def bundle(ui, repo, fname, dest=None, **opts):
1286 def bundle(ui, repo, fname, dest=None, **opts):
1287 """create a changegroup file
1287 """create a changegroup file
1288
1288
1289 Generate a changegroup file collecting changesets to be added
1289 Generate a changegroup file collecting changesets to be added
1290 to a repository.
1290 to a repository.
1291
1291
1292 To create a bundle containing all changesets, use -a/--all
1292 To create a bundle containing all changesets, use -a/--all
1293 (or --base null). Otherwise, hg assumes the destination will have
1293 (or --base null). Otherwise, hg assumes the destination will have
1294 all the nodes you specify with --base parameters. Otherwise, hg
1294 all the nodes you specify with --base parameters. Otherwise, hg
1295 will assume the repository has all the nodes in destination, or
1295 will assume the repository has all the nodes in destination, or
1296 default-push/default if no destination is specified.
1296 default-push/default if no destination is specified.
1297
1297
1298 You can change bundle format with the -t/--type option. You can
1298 You can change bundle format with the -t/--type option. You can
1299 specify a compression, a bundle version or both using a dash
1299 specify a compression, a bundle version or both using a dash
1300 (comp-version). The available compression methods are: none, bzip2,
1300 (comp-version). The available compression methods are: none, bzip2,
1301 and gzip (by default, bundles are compressed using bzip2). The
1301 and gzip (by default, bundles are compressed using bzip2). The
1302 available formats are: v1, v2 (default to most suitable).
1302 available formats are: v1, v2 (default to most suitable).
1303
1303
1304 The bundle file can then be transferred using conventional means
1304 The bundle file can then be transferred using conventional means
1305 and applied to another repository with the unbundle or pull
1305 and applied to another repository with the unbundle or pull
1306 command. This is useful when direct push and pull are not
1306 command. This is useful when direct push and pull are not
1307 available or when exporting an entire repository is undesirable.
1307 available or when exporting an entire repository is undesirable.
1308
1308
1309 Applying bundles preserves all changeset contents including
1309 Applying bundles preserves all changeset contents including
1310 permissions, copy/rename information, and revision history.
1310 permissions, copy/rename information, and revision history.
1311
1311
1312 Returns 0 on success, 1 if no changes found.
1312 Returns 0 on success, 1 if no changes found.
1313 """
1313 """
1314 revs = None
1314 revs = None
1315 if 'rev' in opts:
1315 if 'rev' in opts:
1316 revstrings = opts['rev']
1316 revstrings = opts['rev']
1317 revs = scmutil.revrange(repo, revstrings)
1317 revs = scmutil.revrange(repo, revstrings)
1318 if revstrings and not revs:
1318 if revstrings and not revs:
1319 raise error.Abort(_('no commits to bundle'))
1319 raise error.Abort(_('no commits to bundle'))
1320
1320
1321 bundletype = opts.get('type', 'bzip2').lower()
1321 bundletype = opts.get('type', 'bzip2').lower()
1322 try:
1322 try:
1323 bcompression, cgversion, params = exchange.parsebundlespec(
1323 bcompression, cgversion, params = exchange.parsebundlespec(
1324 repo, bundletype, strict=False)
1324 repo, bundletype, strict=False)
1325 except error.UnsupportedBundleSpecification as e:
1325 except error.UnsupportedBundleSpecification as e:
1326 raise error.Abort(str(e),
1326 raise error.Abort(str(e),
1327 hint=_("see 'hg help bundle' for supported "
1327 hint=_("see 'hg help bundle' for supported "
1328 "values for --type"))
1328 "values for --type"))
1329
1329
1330 # Packed bundles are a pseudo bundle format for now.
1330 # Packed bundles are a pseudo bundle format for now.
1331 if cgversion == 's1':
1331 if cgversion == 's1':
1332 raise error.Abort(_('packed bundles cannot be produced by "hg bundle"'),
1332 raise error.Abort(_('packed bundles cannot be produced by "hg bundle"'),
1333 hint=_("use 'hg debugcreatestreamclonebundle'"))
1333 hint=_("use 'hg debugcreatestreamclonebundle'"))
1334
1334
1335 if opts.get('all'):
1335 if opts.get('all'):
1336 if dest:
1336 if dest:
1337 raise error.Abort(_("--all is incompatible with specifying "
1337 raise error.Abort(_("--all is incompatible with specifying "
1338 "a destination"))
1338 "a destination"))
1339 if opts.get('base'):
1339 if opts.get('base'):
1340 ui.warn(_("ignoring --base because --all was specified\n"))
1340 ui.warn(_("ignoring --base because --all was specified\n"))
1341 base = ['null']
1341 base = ['null']
1342 else:
1342 else:
1343 base = scmutil.revrange(repo, opts.get('base'))
1343 base = scmutil.revrange(repo, opts.get('base'))
1344 # TODO: get desired bundlecaps from command line.
1344 # TODO: get desired bundlecaps from command line.
1345 bundlecaps = None
1345 bundlecaps = None
1346 if cgversion not in changegroup.supportedoutgoingversions(repo):
1346 if cgversion not in changegroup.supportedoutgoingversions(repo):
1347 raise error.Abort(_("repository does not support bundle version %s") %
1347 raise error.Abort(_("repository does not support bundle version %s") %
1348 cgversion)
1348 cgversion)
1349
1349
1350 if base:
1350 if base:
1351 if dest:
1351 if dest:
1352 raise error.Abort(_("--base is incompatible with specifying "
1352 raise error.Abort(_("--base is incompatible with specifying "
1353 "a destination"))
1353 "a destination"))
1354 common = [repo.lookup(rev) for rev in base]
1354 common = [repo.lookup(rev) for rev in base]
1355 heads = revs and map(repo.lookup, revs) or None
1355 heads = revs and map(repo.lookup, revs) or None
1356 outgoing = discovery.outgoing(repo, common, heads)
1356 outgoing = discovery.outgoing(repo, common, heads)
1357 cg = changegroup.getchangegroup(repo, 'bundle', outgoing,
1357 cg = changegroup.getchangegroup(repo, 'bundle', outgoing,
1358 bundlecaps=bundlecaps,
1358 bundlecaps=bundlecaps,
1359 version=cgversion)
1359 version=cgversion)
1360 outgoing = None
1360 outgoing = None
1361 else:
1361 else:
1362 dest = ui.expandpath(dest or 'default-push', dest or 'default')
1362 dest = ui.expandpath(dest or 'default-push', dest or 'default')
1363 dest, branches = hg.parseurl(dest, opts.get('branch'))
1363 dest, branches = hg.parseurl(dest, opts.get('branch'))
1364 other = hg.peer(repo, opts, dest)
1364 other = hg.peer(repo, opts, dest)
1365 revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
1365 revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
1366 heads = revs and map(repo.lookup, revs) or revs
1366 heads = revs and map(repo.lookup, revs) or revs
1367 outgoing = discovery.findcommonoutgoing(repo, other,
1367 outgoing = discovery.findcommonoutgoing(repo, other,
1368 onlyheads=heads,
1368 onlyheads=heads,
1369 force=opts.get('force'),
1369 force=opts.get('force'),
1370 portable=True)
1370 portable=True)
1371 cg = changegroup.getlocalchangegroup(repo, 'bundle', outgoing,
1371 cg = changegroup.getlocalchangegroup(repo, 'bundle', outgoing,
1372 bundlecaps, version=cgversion)
1372 bundlecaps, version=cgversion)
1373 if not cg:
1373 if not cg:
1374 scmutil.nochangesfound(ui, repo, outgoing and outgoing.excluded)
1374 scmutil.nochangesfound(ui, repo, outgoing and outgoing.excluded)
1375 return 1
1375 return 1
1376
1376
1377 if cgversion == '01': #bundle1
1377 if cgversion == '01': #bundle1
1378 if bcompression is None:
1378 if bcompression is None:
1379 bcompression = 'UN'
1379 bcompression = 'UN'
1380 bversion = 'HG10' + bcompression
1380 bversion = 'HG10' + bcompression
1381 bcompression = None
1381 bcompression = None
1382 else:
1382 else:
1383 assert cgversion == '02'
1383 assert cgversion == '02'
1384 bversion = 'HG20'
1384 bversion = 'HG20'
1385
1385
1386 # TODO compression options should be derived from bundlespec parsing.
1386 # TODO compression options should be derived from bundlespec parsing.
1387 # This is a temporary hack to allow adjusting bundle compression
1387 # This is a temporary hack to allow adjusting bundle compression
1388 # level without a) formalizing the bundlespec changes to declare it
1388 # level without a) formalizing the bundlespec changes to declare it
1389 # b) introducing a command flag.
1389 # b) introducing a command flag.
1390 compopts = {}
1390 compopts = {}
1391 complevel = ui.configint('experimental', 'bundlecomplevel')
1391 complevel = ui.configint('experimental', 'bundlecomplevel')
1392 if complevel is not None:
1392 if complevel is not None:
1393 compopts['level'] = complevel
1393 compopts['level'] = complevel
1394
1394
1395 bundle2.writebundle(ui, cg, fname, bversion, compression=bcompression,
1395 bundle2.writebundle(ui, cg, fname, bversion, compression=bcompression,
1396 compopts=compopts)
1396 compopts=compopts)
1397
1397
1398 @command('cat',
1398 @command('cat',
1399 [('o', 'output', '',
1399 [('o', 'output', '',
1400 _('print output to file with formatted name'), _('FORMAT')),
1400 _('print output to file with formatted name'), _('FORMAT')),
1401 ('r', 'rev', '', _('print the given revision'), _('REV')),
1401 ('r', 'rev', '', _('print the given revision'), _('REV')),
1402 ('', 'decode', None, _('apply any matching decode filter')),
1402 ('', 'decode', None, _('apply any matching decode filter')),
1403 ] + walkopts,
1403 ] + walkopts,
1404 _('[OPTION]... FILE...'),
1404 _('[OPTION]... FILE...'),
1405 inferrepo=True)
1405 inferrepo=True)
1406 def cat(ui, repo, file1, *pats, **opts):
1406 def cat(ui, repo, file1, *pats, **opts):
1407 """output the current or given revision of files
1407 """output the current or given revision of files
1408
1408
1409 Print the specified files as they were at the given revision. If
1409 Print the specified files as they were at the given revision. If
1410 no revision is given, the parent of the working directory is used.
1410 no revision is given, the parent of the working directory is used.
1411
1411
1412 Output may be to a file, in which case the name of the file is
1412 Output may be to a file, in which case the name of the file is
1413 given using a format string. The formatting rules as follows:
1413 given using a format string. The formatting rules as follows:
1414
1414
1415 :``%%``: literal "%" character
1415 :``%%``: literal "%" character
1416 :``%s``: basename of file being printed
1416 :``%s``: basename of file being printed
1417 :``%d``: dirname of file being printed, or '.' if in repository root
1417 :``%d``: dirname of file being printed, or '.' if in repository root
1418 :``%p``: root-relative path name of file being printed
1418 :``%p``: root-relative path name of file being printed
1419 :``%H``: changeset hash (40 hexadecimal digits)
1419 :``%H``: changeset hash (40 hexadecimal digits)
1420 :``%R``: changeset revision number
1420 :``%R``: changeset revision number
1421 :``%h``: short-form changeset hash (12 hexadecimal digits)
1421 :``%h``: short-form changeset hash (12 hexadecimal digits)
1422 :``%r``: zero-padded changeset revision number
1422 :``%r``: zero-padded changeset revision number
1423 :``%b``: basename of the exporting repository
1423 :``%b``: basename of the exporting repository
1424
1424
1425 Returns 0 on success.
1425 Returns 0 on success.
1426 """
1426 """
1427 ctx = scmutil.revsingle(repo, opts.get('rev'))
1427 ctx = scmutil.revsingle(repo, opts.get('rev'))
1428 m = scmutil.match(ctx, (file1,) + pats, opts)
1428 m = scmutil.match(ctx, (file1,) + pats, opts)
1429
1429
1430 return cmdutil.cat(ui, repo, ctx, m, '', **opts)
1430 return cmdutil.cat(ui, repo, ctx, m, '', **opts)
1431
1431
1432 @command('^clone',
1432 @command('^clone',
1433 [('U', 'noupdate', None, _('the clone will include an empty working '
1433 [('U', 'noupdate', None, _('the clone will include an empty working '
1434 'directory (only a repository)')),
1434 'directory (only a repository)')),
1435 ('u', 'updaterev', '', _('revision, tag, or branch to check out'),
1435 ('u', 'updaterev', '', _('revision, tag, or branch to check out'),
1436 _('REV')),
1436 _('REV')),
1437 ('r', 'rev', [], _('include the specified changeset'), _('REV')),
1437 ('r', 'rev', [], _('include the specified changeset'), _('REV')),
1438 ('b', 'branch', [], _('clone only the specified branch'), _('BRANCH')),
1438 ('b', 'branch', [], _('clone only the specified branch'), _('BRANCH')),
1439 ('', 'pull', None, _('use pull protocol to copy metadata')),
1439 ('', 'pull', None, _('use pull protocol to copy metadata')),
1440 ('', 'uncompressed', None, _('use uncompressed transfer (fast over LAN)')),
1440 ('', 'uncompressed', None, _('use uncompressed transfer (fast over LAN)')),
1441 ] + remoteopts,
1441 ] + remoteopts,
1442 _('[OPTION]... SOURCE [DEST]'),
1442 _('[OPTION]... SOURCE [DEST]'),
1443 norepo=True)
1443 norepo=True)
1444 def clone(ui, source, dest=None, **opts):
1444 def clone(ui, source, dest=None, **opts):
1445 """make a copy of an existing repository
1445 """make a copy of an existing repository
1446
1446
1447 Create a copy of an existing repository in a new directory.
1447 Create a copy of an existing repository in a new directory.
1448
1448
1449 If no destination directory name is specified, it defaults to the
1449 If no destination directory name is specified, it defaults to the
1450 basename of the source.
1450 basename of the source.
1451
1451
1452 The location of the source is added to the new repository's
1452 The location of the source is added to the new repository's
1453 ``.hg/hgrc`` file, as the default to be used for future pulls.
1453 ``.hg/hgrc`` file, as the default to be used for future pulls.
1454
1454
1455 Only local paths and ``ssh://`` URLs are supported as
1455 Only local paths and ``ssh://`` URLs are supported as
1456 destinations. For ``ssh://`` destinations, no working directory or
1456 destinations. For ``ssh://`` destinations, no working directory or
1457 ``.hg/hgrc`` will be created on the remote side.
1457 ``.hg/hgrc`` will be created on the remote side.
1458
1458
1459 If the source repository has a bookmark called '@' set, that
1459 If the source repository has a bookmark called '@' set, that
1460 revision will be checked out in the new repository by default.
1460 revision will be checked out in the new repository by default.
1461
1461
1462 To check out a particular version, use -u/--update, or
1462 To check out a particular version, use -u/--update, or
1463 -U/--noupdate to create a clone with no working directory.
1463 -U/--noupdate to create a clone with no working directory.
1464
1464
1465 To pull only a subset of changesets, specify one or more revisions
1465 To pull only a subset of changesets, specify one or more revisions
1466 identifiers with -r/--rev or branches with -b/--branch. The
1466 identifiers with -r/--rev or branches with -b/--branch. The
1467 resulting clone will contain only the specified changesets and
1467 resulting clone will contain only the specified changesets and
1468 their ancestors. These options (or 'clone src#rev dest') imply
1468 their ancestors. These options (or 'clone src#rev dest') imply
1469 --pull, even for local source repositories.
1469 --pull, even for local source repositories.
1470
1470
1471 .. note::
1471 .. note::
1472
1472
1473 Specifying a tag will include the tagged changeset but not the
1473 Specifying a tag will include the tagged changeset but not the
1474 changeset containing the tag.
1474 changeset containing the tag.
1475
1475
1476 .. container:: verbose
1476 .. container:: verbose
1477
1477
1478 For efficiency, hardlinks are used for cloning whenever the
1478 For efficiency, hardlinks are used for cloning whenever the
1479 source and destination are on the same filesystem (note this
1479 source and destination are on the same filesystem (note this
1480 applies only to the repository data, not to the working
1480 applies only to the repository data, not to the working
1481 directory). Some filesystems, such as AFS, implement hardlinking
1481 directory). Some filesystems, such as AFS, implement hardlinking
1482 incorrectly, but do not report errors. In these cases, use the
1482 incorrectly, but do not report errors. In these cases, use the
1483 --pull option to avoid hardlinking.
1483 --pull option to avoid hardlinking.
1484
1484
1485 In some cases, you can clone repositories and the working
1485 In some cases, you can clone repositories and the working
1486 directory using full hardlinks with ::
1486 directory using full hardlinks with ::
1487
1487
1488 $ cp -al REPO REPOCLONE
1488 $ cp -al REPO REPOCLONE
1489
1489
1490 This is the fastest way to clone, but it is not always safe. The
1490 This is the fastest way to clone, but it is not always safe. The
1491 operation is not atomic (making sure REPO is not modified during
1491 operation is not atomic (making sure REPO is not modified during
1492 the operation is up to you) and you have to make sure your
1492 the operation is up to you) and you have to make sure your
1493 editor breaks hardlinks (Emacs and most Linux Kernel tools do
1493 editor breaks hardlinks (Emacs and most Linux Kernel tools do
1494 so). Also, this is not compatible with certain extensions that
1494 so). Also, this is not compatible with certain extensions that
1495 place their metadata under the .hg directory, such as mq.
1495 place their metadata under the .hg directory, such as mq.
1496
1496
1497 Mercurial will update the working directory to the first applicable
1497 Mercurial will update the working directory to the first applicable
1498 revision from this list:
1498 revision from this list:
1499
1499
1500 a) null if -U or the source repository has no changesets
1500 a) null if -U or the source repository has no changesets
1501 b) if -u . and the source repository is local, the first parent of
1501 b) if -u . and the source repository is local, the first parent of
1502 the source repository's working directory
1502 the source repository's working directory
1503 c) the changeset specified with -u (if a branch name, this means the
1503 c) the changeset specified with -u (if a branch name, this means the
1504 latest head of that branch)
1504 latest head of that branch)
1505 d) the changeset specified with -r
1505 d) the changeset specified with -r
1506 e) the tipmost head specified with -b
1506 e) the tipmost head specified with -b
1507 f) the tipmost head specified with the url#branch source syntax
1507 f) the tipmost head specified with the url#branch source syntax
1508 g) the revision marked with the '@' bookmark, if present
1508 g) the revision marked with the '@' bookmark, if present
1509 h) the tipmost head of the default branch
1509 h) the tipmost head of the default branch
1510 i) tip
1510 i) tip
1511
1511
1512 When cloning from servers that support it, Mercurial may fetch
1512 When cloning from servers that support it, Mercurial may fetch
1513 pre-generated data from a server-advertised URL. When this is done,
1513 pre-generated data from a server-advertised URL. When this is done,
1514 hooks operating on incoming changesets and changegroups may fire twice,
1514 hooks operating on incoming changesets and changegroups may fire twice,
1515 once for the bundle fetched from the URL and another for any additional
1515 once for the bundle fetched from the URL and another for any additional
1516 data not fetched from this URL. In addition, if an error occurs, the
1516 data not fetched from this URL. In addition, if an error occurs, the
1517 repository may be rolled back to a partial clone. This behavior may
1517 repository may be rolled back to a partial clone. This behavior may
1518 change in future releases. See :hg:`help -e clonebundles` for more.
1518 change in future releases. See :hg:`help -e clonebundles` for more.
1519
1519
1520 Examples:
1520 Examples:
1521
1521
1522 - clone a remote repository to a new directory named hg/::
1522 - clone a remote repository to a new directory named hg/::
1523
1523
1524 hg clone https://www.mercurial-scm.org/repo/hg/
1524 hg clone https://www.mercurial-scm.org/repo/hg/
1525
1525
1526 - create a lightweight local clone::
1526 - create a lightweight local clone::
1527
1527
1528 hg clone project/ project-feature/
1528 hg clone project/ project-feature/
1529
1529
1530 - clone from an absolute path on an ssh server (note double-slash)::
1530 - clone from an absolute path on an ssh server (note double-slash)::
1531
1531
1532 hg clone ssh://user@server//home/projects/alpha/
1532 hg clone ssh://user@server//home/projects/alpha/
1533
1533
1534 - do a high-speed clone over a LAN while checking out a
1534 - do a high-speed clone over a LAN while checking out a
1535 specified version::
1535 specified version::
1536
1536
1537 hg clone --uncompressed http://server/repo -u 1.5
1537 hg clone --uncompressed http://server/repo -u 1.5
1538
1538
1539 - create a repository without changesets after a particular revision::
1539 - create a repository without changesets after a particular revision::
1540
1540
1541 hg clone -r 04e544 experimental/ good/
1541 hg clone -r 04e544 experimental/ good/
1542
1542
1543 - clone (and track) a particular named branch::
1543 - clone (and track) a particular named branch::
1544
1544
1545 hg clone https://www.mercurial-scm.org/repo/hg/#stable
1545 hg clone https://www.mercurial-scm.org/repo/hg/#stable
1546
1546
1547 See :hg:`help urls` for details on specifying URLs.
1547 See :hg:`help urls` for details on specifying URLs.
1548
1548
1549 Returns 0 on success.
1549 Returns 0 on success.
1550 """
1550 """
1551 if opts.get('noupdate') and opts.get('updaterev'):
1551 if opts.get('noupdate') and opts.get('updaterev'):
1552 raise error.Abort(_("cannot specify both --noupdate and --updaterev"))
1552 raise error.Abort(_("cannot specify both --noupdate and --updaterev"))
1553
1553
1554 r = hg.clone(ui, opts, source, dest,
1554 r = hg.clone(ui, opts, source, dest,
1555 pull=opts.get('pull'),
1555 pull=opts.get('pull'),
1556 stream=opts.get('uncompressed'),
1556 stream=opts.get('uncompressed'),
1557 rev=opts.get('rev'),
1557 rev=opts.get('rev'),
1558 update=opts.get('updaterev') or not opts.get('noupdate'),
1558 update=opts.get('updaterev') or not opts.get('noupdate'),
1559 branch=opts.get('branch'),
1559 branch=opts.get('branch'),
1560 shareopts=opts.get('shareopts'))
1560 shareopts=opts.get('shareopts'))
1561
1561
1562 return r is None
1562 return r is None
1563
1563
1564 @command('^commit|ci',
1564 @command('^commit|ci',
1565 [('A', 'addremove', None,
1565 [('A', 'addremove', None,
1566 _('mark new/missing files as added/removed before committing')),
1566 _('mark new/missing files as added/removed before committing')),
1567 ('', 'close-branch', None,
1567 ('', 'close-branch', None,
1568 _('mark a branch head as closed')),
1568 _('mark a branch head as closed')),
1569 ('', 'amend', None, _('amend the parent of the working directory')),
1569 ('', 'amend', None, _('amend the parent of the working directory')),
1570 ('s', 'secret', None, _('use the secret phase for committing')),
1570 ('s', 'secret', None, _('use the secret phase for committing')),
1571 ('e', 'edit', None, _('invoke editor on commit messages')),
1571 ('e', 'edit', None, _('invoke editor on commit messages')),
1572 ('i', 'interactive', None, _('use interactive mode')),
1572 ('i', 'interactive', None, _('use interactive mode')),
1573 ] + walkopts + commitopts + commitopts2 + subrepoopts,
1573 ] + walkopts + commitopts + commitopts2 + subrepoopts,
1574 _('[OPTION]... [FILE]...'),
1574 _('[OPTION]... [FILE]...'),
1575 inferrepo=True)
1575 inferrepo=True)
1576 def commit(ui, repo, *pats, **opts):
1576 def commit(ui, repo, *pats, **opts):
1577 """commit the specified files or all outstanding changes
1577 """commit the specified files or all outstanding changes
1578
1578
1579 Commit changes to the given files into the repository. Unlike a
1579 Commit changes to the given files into the repository. Unlike a
1580 centralized SCM, this operation is a local operation. See
1580 centralized SCM, this operation is a local operation. See
1581 :hg:`push` for a way to actively distribute your changes.
1581 :hg:`push` for a way to actively distribute your changes.
1582
1582
1583 If a list of files is omitted, all changes reported by :hg:`status`
1583 If a list of files is omitted, all changes reported by :hg:`status`
1584 will be committed.
1584 will be committed.
1585
1585
1586 If you are committing the result of a merge, do not provide any
1586 If you are committing the result of a merge, do not provide any
1587 filenames or -I/-X filters.
1587 filenames or -I/-X filters.
1588
1588
1589 If no commit message is specified, Mercurial starts your
1589 If no commit message is specified, Mercurial starts your
1590 configured editor where you can enter a message. In case your
1590 configured editor where you can enter a message. In case your
1591 commit fails, you will find a backup of your message in
1591 commit fails, you will find a backup of your message in
1592 ``.hg/last-message.txt``.
1592 ``.hg/last-message.txt``.
1593
1593
1594 The --close-branch flag can be used to mark the current branch
1594 The --close-branch flag can be used to mark the current branch
1595 head closed. When all heads of a branch are closed, the branch
1595 head closed. When all heads of a branch are closed, the branch
1596 will be considered closed and no longer listed.
1596 will be considered closed and no longer listed.
1597
1597
1598 The --amend flag can be used to amend the parent of the
1598 The --amend flag can be used to amend the parent of the
1599 working directory with a new commit that contains the changes
1599 working directory with a new commit that contains the changes
1600 in the parent in addition to those currently reported by :hg:`status`,
1600 in the parent in addition to those currently reported by :hg:`status`,
1601 if there are any. The old commit is stored in a backup bundle in
1601 if there are any. The old commit is stored in a backup bundle in
1602 ``.hg/strip-backup`` (see :hg:`help bundle` and :hg:`help unbundle`
1602 ``.hg/strip-backup`` (see :hg:`help bundle` and :hg:`help unbundle`
1603 on how to restore it).
1603 on how to restore it).
1604
1604
1605 Message, user and date are taken from the amended commit unless
1605 Message, user and date are taken from the amended commit unless
1606 specified. When a message isn't specified on the command line,
1606 specified. When a message isn't specified on the command line,
1607 the editor will open with the message of the amended commit.
1607 the editor will open with the message of the amended commit.
1608
1608
1609 It is not possible to amend public changesets (see :hg:`help phases`)
1609 It is not possible to amend public changesets (see :hg:`help phases`)
1610 or changesets that have children.
1610 or changesets that have children.
1611
1611
1612 See :hg:`help dates` for a list of formats valid for -d/--date.
1612 See :hg:`help dates` for a list of formats valid for -d/--date.
1613
1613
1614 Returns 0 on success, 1 if nothing changed.
1614 Returns 0 on success, 1 if nothing changed.
1615
1615
1616 .. container:: verbose
1616 .. container:: verbose
1617
1617
1618 Examples:
1618 Examples:
1619
1619
1620 - commit all files ending in .py::
1620 - commit all files ending in .py::
1621
1621
1622 hg commit --include "set:**.py"
1622 hg commit --include "set:**.py"
1623
1623
1624 - commit all non-binary files::
1624 - commit all non-binary files::
1625
1625
1626 hg commit --exclude "set:binary()"
1626 hg commit --exclude "set:binary()"
1627
1627
1628 - amend the current commit and set the date to now::
1628 - amend the current commit and set the date to now::
1629
1629
1630 hg commit --amend --date now
1630 hg commit --amend --date now
1631 """
1631 """
1632 wlock = lock = None
1632 wlock = lock = None
1633 try:
1633 try:
1634 wlock = repo.wlock()
1634 wlock = repo.wlock()
1635 lock = repo.lock()
1635 lock = repo.lock()
1636 return _docommit(ui, repo, *pats, **opts)
1636 return _docommit(ui, repo, *pats, **opts)
1637 finally:
1637 finally:
1638 release(lock, wlock)
1638 release(lock, wlock)
1639
1639
1640 def _docommit(ui, repo, *pats, **opts):
1640 def _docommit(ui, repo, *pats, **opts):
1641 if opts.get('interactive'):
1641 if opts.get('interactive'):
1642 opts.pop('interactive')
1642 opts.pop('interactive')
1643 ret = cmdutil.dorecord(ui, repo, commit, None, False,
1643 ret = cmdutil.dorecord(ui, repo, commit, None, False,
1644 cmdutil.recordfilter, *pats, **opts)
1644 cmdutil.recordfilter, *pats, **opts)
1645 # ret can be 0 (no changes to record) or the value returned by
1645 # ret can be 0 (no changes to record) or the value returned by
1646 # commit(), 1 if nothing changed or None on success.
1646 # commit(), 1 if nothing changed or None on success.
1647 return 1 if ret == 0 else ret
1647 return 1 if ret == 0 else ret
1648
1648
1649 if opts.get('subrepos'):
1649 if opts.get('subrepos'):
1650 if opts.get('amend'):
1650 if opts.get('amend'):
1651 raise error.Abort(_('cannot amend with --subrepos'))
1651 raise error.Abort(_('cannot amend with --subrepos'))
1652 # Let --subrepos on the command line override config setting.
1652 # Let --subrepos on the command line override config setting.
1653 ui.setconfig('ui', 'commitsubrepos', True, 'commit')
1653 ui.setconfig('ui', 'commitsubrepos', True, 'commit')
1654
1654
1655 cmdutil.checkunfinished(repo, commit=True)
1655 cmdutil.checkunfinished(repo, commit=True)
1656
1656
1657 branch = repo[None].branch()
1657 branch = repo[None].branch()
1658 bheads = repo.branchheads(branch)
1658 bheads = repo.branchheads(branch)
1659
1659
1660 extra = {}
1660 extra = {}
1661 if opts.get('close_branch'):
1661 if opts.get('close_branch'):
1662 extra['close'] = 1
1662 extra['close'] = 1
1663
1663
1664 if not bheads:
1664 if not bheads:
1665 raise error.Abort(_('can only close branch heads'))
1665 raise error.Abort(_('can only close branch heads'))
1666 elif opts.get('amend'):
1666 elif opts.get('amend'):
1667 if repo[None].parents()[0].p1().branch() != branch and \
1667 if repo[None].parents()[0].p1().branch() != branch and \
1668 repo[None].parents()[0].p2().branch() != branch:
1668 repo[None].parents()[0].p2().branch() != branch:
1669 raise error.Abort(_('can only close branch heads'))
1669 raise error.Abort(_('can only close branch heads'))
1670
1670
1671 if opts.get('amend'):
1671 if opts.get('amend'):
1672 if ui.configbool('ui', 'commitsubrepos'):
1672 if ui.configbool('ui', 'commitsubrepos'):
1673 raise error.Abort(_('cannot amend with ui.commitsubrepos enabled'))
1673 raise error.Abort(_('cannot amend with ui.commitsubrepos enabled'))
1674
1674
1675 old = repo['.']
1675 old = repo['.']
1676 if not old.mutable():
1676 if not old.mutable():
1677 raise error.Abort(_('cannot amend public changesets'))
1677 raise error.Abort(_('cannot amend public changesets'))
1678 if len(repo[None].parents()) > 1:
1678 if len(repo[None].parents()) > 1:
1679 raise error.Abort(_('cannot amend while merging'))
1679 raise error.Abort(_('cannot amend while merging'))
1680 allowunstable = obsolete.isenabled(repo, obsolete.allowunstableopt)
1680 allowunstable = obsolete.isenabled(repo, obsolete.allowunstableopt)
1681 if not allowunstable and old.children():
1681 if not allowunstable and old.children():
1682 raise error.Abort(_('cannot amend changeset with children'))
1682 raise error.Abort(_('cannot amend changeset with children'))
1683
1683
1684 # Currently histedit gets confused if an amend happens while histedit
1684 # Currently histedit gets confused if an amend happens while histedit
1685 # is in progress. Since we have a checkunfinished command, we are
1685 # is in progress. Since we have a checkunfinished command, we are
1686 # temporarily honoring it.
1686 # temporarily honoring it.
1687 #
1687 #
1688 # Note: eventually this guard will be removed. Please do not expect
1688 # Note: eventually this guard will be removed. Please do not expect
1689 # this behavior to remain.
1689 # this behavior to remain.
1690 if not obsolete.isenabled(repo, obsolete.createmarkersopt):
1690 if not obsolete.isenabled(repo, obsolete.createmarkersopt):
1691 cmdutil.checkunfinished(repo)
1691 cmdutil.checkunfinished(repo)
1692
1692
1693 # commitfunc is used only for temporary amend commit by cmdutil.amend
1693 # commitfunc is used only for temporary amend commit by cmdutil.amend
1694 def commitfunc(ui, repo, message, match, opts):
1694 def commitfunc(ui, repo, message, match, opts):
1695 return repo.commit(message,
1695 return repo.commit(message,
1696 opts.get('user') or old.user(),
1696 opts.get('user') or old.user(),
1697 opts.get('date') or old.date(),
1697 opts.get('date') or old.date(),
1698 match,
1698 match,
1699 extra=extra)
1699 extra=extra)
1700
1700
1701 node = cmdutil.amend(ui, repo, commitfunc, old, extra, pats, opts)
1701 node = cmdutil.amend(ui, repo, commitfunc, old, extra, pats, opts)
1702 if node == old.node():
1702 if node == old.node():
1703 ui.status(_("nothing changed\n"))
1703 ui.status(_("nothing changed\n"))
1704 return 1
1704 return 1
1705 else:
1705 else:
1706 def commitfunc(ui, repo, message, match, opts):
1706 def commitfunc(ui, repo, message, match, opts):
1707 backup = ui.backupconfig('phases', 'new-commit')
1707 backup = ui.backupconfig('phases', 'new-commit')
1708 baseui = repo.baseui
1708 baseui = repo.baseui
1709 basebackup = baseui.backupconfig('phases', 'new-commit')
1709 basebackup = baseui.backupconfig('phases', 'new-commit')
1710 try:
1710 try:
1711 if opts.get('secret'):
1711 if opts.get('secret'):
1712 ui.setconfig('phases', 'new-commit', 'secret', 'commit')
1712 ui.setconfig('phases', 'new-commit', 'secret', 'commit')
1713 # Propagate to subrepos
1713 # Propagate to subrepos
1714 baseui.setconfig('phases', 'new-commit', 'secret', 'commit')
1714 baseui.setconfig('phases', 'new-commit', 'secret', 'commit')
1715
1715
1716 editform = cmdutil.mergeeditform(repo[None], 'commit.normal')
1716 editform = cmdutil.mergeeditform(repo[None], 'commit.normal')
1717 editor = cmdutil.getcommiteditor(editform=editform, **opts)
1717 editor = cmdutil.getcommiteditor(editform=editform, **opts)
1718 return repo.commit(message, opts.get('user'), opts.get('date'),
1718 return repo.commit(message, opts.get('user'), opts.get('date'),
1719 match,
1719 match,
1720 editor=editor,
1720 editor=editor,
1721 extra=extra)
1721 extra=extra)
1722 finally:
1722 finally:
1723 ui.restoreconfig(backup)
1723 ui.restoreconfig(backup)
1724 repo.baseui.restoreconfig(basebackup)
1724 repo.baseui.restoreconfig(basebackup)
1725
1725
1726
1726
1727 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
1727 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
1728
1728
1729 if not node:
1729 if not node:
1730 stat = cmdutil.postcommitstatus(repo, pats, opts)
1730 stat = cmdutil.postcommitstatus(repo, pats, opts)
1731 if stat[3]:
1731 if stat[3]:
1732 ui.status(_("nothing changed (%d missing files, see "
1732 ui.status(_("nothing changed (%d missing files, see "
1733 "'hg status')\n") % len(stat[3]))
1733 "'hg status')\n") % len(stat[3]))
1734 else:
1734 else:
1735 ui.status(_("nothing changed\n"))
1735 ui.status(_("nothing changed\n"))
1736 return 1
1736 return 1
1737
1737
1738 cmdutil.commitstatus(repo, node, branch, bheads, opts)
1738 cmdutil.commitstatus(repo, node, branch, bheads, opts)
1739
1739
1740 @command('config|showconfig|debugconfig',
1740 @command('config|showconfig|debugconfig',
1741 [('u', 'untrusted', None, _('show untrusted configuration options')),
1741 [('u', 'untrusted', None, _('show untrusted configuration options')),
1742 ('e', 'edit', None, _('edit user config')),
1742 ('e', 'edit', None, _('edit user config')),
1743 ('l', 'local', None, _('edit repository config')),
1743 ('l', 'local', None, _('edit repository config')),
1744 ('g', 'global', None, _('edit global config'))] + formatteropts,
1744 ('g', 'global', None, _('edit global config'))] + formatteropts,
1745 _('[-u] [NAME]...'),
1745 _('[-u] [NAME]...'),
1746 optionalrepo=True)
1746 optionalrepo=True)
1747 def config(ui, repo, *values, **opts):
1747 def config(ui, repo, *values, **opts):
1748 """show combined config settings from all hgrc files
1748 """show combined config settings from all hgrc files
1749
1749
1750 With no arguments, print names and values of all config items.
1750 With no arguments, print names and values of all config items.
1751
1751
1752 With one argument of the form section.name, print just the value
1752 With one argument of the form section.name, print just the value
1753 of that config item.
1753 of that config item.
1754
1754
1755 With multiple arguments, print names and values of all config
1755 With multiple arguments, print names and values of all config
1756 items with matching section names.
1756 items with matching section names.
1757
1757
1758 With --edit, start an editor on the user-level config file. With
1758 With --edit, start an editor on the user-level config file. With
1759 --global, edit the system-wide config file. With --local, edit the
1759 --global, edit the system-wide config file. With --local, edit the
1760 repository-level config file.
1760 repository-level config file.
1761
1761
1762 With --debug, the source (filename and line number) is printed
1762 With --debug, the source (filename and line number) is printed
1763 for each config item.
1763 for each config item.
1764
1764
1765 See :hg:`help config` for more information about config files.
1765 See :hg:`help config` for more information about config files.
1766
1766
1767 Returns 0 on success, 1 if NAME does not exist.
1767 Returns 0 on success, 1 if NAME does not exist.
1768
1768
1769 """
1769 """
1770
1770
1771 if opts.get('edit') or opts.get('local') or opts.get('global'):
1771 if opts.get('edit') or opts.get('local') or opts.get('global'):
1772 if opts.get('local') and opts.get('global'):
1772 if opts.get('local') and opts.get('global'):
1773 raise error.Abort(_("can't use --local and --global together"))
1773 raise error.Abort(_("can't use --local and --global together"))
1774
1774
1775 if opts.get('local'):
1775 if opts.get('local'):
1776 if not repo:
1776 if not repo:
1777 raise error.Abort(_("can't use --local outside a repository"))
1777 raise error.Abort(_("can't use --local outside a repository"))
1778 paths = [repo.join('hgrc')]
1778 paths = [repo.join('hgrc')]
1779 elif opts.get('global'):
1779 elif opts.get('global'):
1780 paths = scmutil.systemrcpath()
1780 paths = scmutil.systemrcpath()
1781 else:
1781 else:
1782 paths = scmutil.userrcpath()
1782 paths = scmutil.userrcpath()
1783
1783
1784 for f in paths:
1784 for f in paths:
1785 if os.path.exists(f):
1785 if os.path.exists(f):
1786 break
1786 break
1787 else:
1787 else:
1788 if opts.get('global'):
1788 if opts.get('global'):
1789 samplehgrc = uimod.samplehgrcs['global']
1789 samplehgrc = uimod.samplehgrcs['global']
1790 elif opts.get('local'):
1790 elif opts.get('local'):
1791 samplehgrc = uimod.samplehgrcs['local']
1791 samplehgrc = uimod.samplehgrcs['local']
1792 else:
1792 else:
1793 samplehgrc = uimod.samplehgrcs['user']
1793 samplehgrc = uimod.samplehgrcs['user']
1794
1794
1795 f = paths[0]
1795 f = paths[0]
1796 fp = open(f, "w")
1796 fp = open(f, "w")
1797 fp.write(samplehgrc)
1797 fp.write(samplehgrc)
1798 fp.close()
1798 fp.close()
1799
1799
1800 editor = ui.geteditor()
1800 editor = ui.geteditor()
1801 ui.system("%s \"%s\"" % (editor, f),
1801 ui.system("%s \"%s\"" % (editor, f),
1802 onerr=error.Abort, errprefix=_("edit failed"))
1802 onerr=error.Abort, errprefix=_("edit failed"))
1803 return
1803 return
1804
1804
1805 fm = ui.formatter('config', opts)
1805 fm = ui.formatter('config', opts)
1806 for f in scmutil.rcpath():
1806 for f in scmutil.rcpath():
1807 ui.debug('read config from: %s\n' % f)
1807 ui.debug('read config from: %s\n' % f)
1808 untrusted = bool(opts.get('untrusted'))
1808 untrusted = bool(opts.get('untrusted'))
1809 if values:
1809 if values:
1810 sections = [v for v in values if '.' not in v]
1810 sections = [v for v in values if '.' not in v]
1811 items = [v for v in values if '.' in v]
1811 items = [v for v in values if '.' in v]
1812 if len(items) > 1 or items and sections:
1812 if len(items) > 1 or items and sections:
1813 raise error.Abort(_('only one config item permitted'))
1813 raise error.Abort(_('only one config item permitted'))
1814 matched = False
1814 matched = False
1815 for section, name, value in ui.walkconfig(untrusted=untrusted):
1815 for section, name, value in ui.walkconfig(untrusted=untrusted):
1816 source = ui.configsource(section, name, untrusted)
1816 source = ui.configsource(section, name, untrusted)
1817 value = str(value)
1817 value = str(value)
1818 if fm.isplain():
1818 if fm.isplain():
1819 source = source or 'none'
1819 source = source or 'none'
1820 value = value.replace('\n', '\\n')
1820 value = value.replace('\n', '\\n')
1821 entryname = section + '.' + name
1821 entryname = section + '.' + name
1822 if values:
1822 if values:
1823 for v in values:
1823 for v in values:
1824 if v == section:
1824 if v == section:
1825 fm.startitem()
1825 fm.startitem()
1826 fm.condwrite(ui.debugflag, 'source', '%s: ', source)
1826 fm.condwrite(ui.debugflag, 'source', '%s: ', source)
1827 fm.write('name value', '%s=%s\n', entryname, value)
1827 fm.write('name value', '%s=%s\n', entryname, value)
1828 matched = True
1828 matched = True
1829 elif v == entryname:
1829 elif v == entryname:
1830 fm.startitem()
1830 fm.startitem()
1831 fm.condwrite(ui.debugflag, 'source', '%s: ', source)
1831 fm.condwrite(ui.debugflag, 'source', '%s: ', source)
1832 fm.write('value', '%s\n', value)
1832 fm.write('value', '%s\n', value)
1833 fm.data(name=entryname)
1833 fm.data(name=entryname)
1834 matched = True
1834 matched = True
1835 else:
1835 else:
1836 fm.startitem()
1836 fm.startitem()
1837 fm.condwrite(ui.debugflag, 'source', '%s: ', source)
1837 fm.condwrite(ui.debugflag, 'source', '%s: ', source)
1838 fm.write('name value', '%s=%s\n', entryname, value)
1838 fm.write('name value', '%s=%s\n', entryname, value)
1839 matched = True
1839 matched = True
1840 fm.end()
1840 fm.end()
1841 if matched:
1841 if matched:
1842 return 0
1842 return 0
1843 return 1
1843 return 1
1844
1844
1845 @command('copy|cp',
1845 @command('copy|cp',
1846 [('A', 'after', None, _('record a copy that has already occurred')),
1846 [('A', 'after', None, _('record a copy that has already occurred')),
1847 ('f', 'force', None, _('forcibly copy over an existing managed file')),
1847 ('f', 'force', None, _('forcibly copy over an existing managed file')),
1848 ] + walkopts + dryrunopts,
1848 ] + walkopts + dryrunopts,
1849 _('[OPTION]... [SOURCE]... DEST'))
1849 _('[OPTION]... [SOURCE]... DEST'))
1850 def copy(ui, repo, *pats, **opts):
1850 def copy(ui, repo, *pats, **opts):
1851 """mark files as copied for the next commit
1851 """mark files as copied for the next commit
1852
1852
1853 Mark dest as having copies of source files. If dest is a
1853 Mark dest as having copies of source files. If dest is a
1854 directory, copies are put in that directory. If dest is a file,
1854 directory, copies are put in that directory. If dest is a file,
1855 the source must be a single file.
1855 the source must be a single file.
1856
1856
1857 By default, this command copies the contents of files as they
1857 By default, this command copies the contents of files as they
1858 exist in the working directory. If invoked with -A/--after, the
1858 exist in the working directory. If invoked with -A/--after, the
1859 operation is recorded, but no copying is performed.
1859 operation is recorded, but no copying is performed.
1860
1860
1861 This command takes effect with the next commit. To undo a copy
1861 This command takes effect with the next commit. To undo a copy
1862 before that, see :hg:`revert`.
1862 before that, see :hg:`revert`.
1863
1863
1864 Returns 0 on success, 1 if errors are encountered.
1864 Returns 0 on success, 1 if errors are encountered.
1865 """
1865 """
1866 with repo.wlock(False):
1866 with repo.wlock(False):
1867 return cmdutil.copy(ui, repo, pats, opts)
1867 return cmdutil.copy(ui, repo, pats, opts)
1868
1868
1869 @command('debuginstall', [] + formatteropts, '', norepo=True)
1869 @command('debuginstall', [] + formatteropts, '', norepo=True)
1870 def debuginstall(ui, **opts):
1870 def debuginstall(ui, **opts):
1871 '''test Mercurial installation
1871 '''test Mercurial installation
1872
1872
1873 Returns 0 on success.
1873 Returns 0 on success.
1874 '''
1874 '''
1875
1875
1876 def writetemp(contents):
1876 def writetemp(contents):
1877 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
1877 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
1878 f = os.fdopen(fd, "wb")
1878 f = os.fdopen(fd, "wb")
1879 f.write(contents)
1879 f.write(contents)
1880 f.close()
1880 f.close()
1881 return name
1881 return name
1882
1882
1883 problems = 0
1883 problems = 0
1884
1884
1885 fm = ui.formatter('debuginstall', opts)
1885 fm = ui.formatter('debuginstall', opts)
1886 fm.startitem()
1886 fm.startitem()
1887
1887
1888 # encoding
1888 # encoding
1889 fm.write('encoding', _("checking encoding (%s)...\n"), encoding.encoding)
1889 fm.write('encoding', _("checking encoding (%s)...\n"), encoding.encoding)
1890 err = None
1890 err = None
1891 try:
1891 try:
1892 encoding.fromlocal("test")
1892 encoding.fromlocal("test")
1893 except error.Abort as inst:
1893 except error.Abort as inst:
1894 err = inst
1894 err = inst
1895 problems += 1
1895 problems += 1
1896 fm.condwrite(err, 'encodingerror', _(" %s\n"
1896 fm.condwrite(err, 'encodingerror', _(" %s\n"
1897 " (check that your locale is properly set)\n"), err)
1897 " (check that your locale is properly set)\n"), err)
1898
1898
1899 # Python
1899 # Python
1900 fm.write('pythonexe', _("checking Python executable (%s)\n"),
1900 fm.write('pythonexe', _("checking Python executable (%s)\n"),
1901 pycompat.sysexecutable)
1901 pycompat.sysexecutable)
1902 fm.write('pythonver', _("checking Python version (%s)\n"),
1902 fm.write('pythonver', _("checking Python version (%s)\n"),
1903 ("%d.%d.%d" % sys.version_info[:3]))
1903 ("%d.%d.%d" % sys.version_info[:3]))
1904 fm.write('pythonlib', _("checking Python lib (%s)...\n"),
1904 fm.write('pythonlib', _("checking Python lib (%s)...\n"),
1905 os.path.dirname(os.__file__))
1905 os.path.dirname(os.__file__))
1906
1906
1907 security = set(sslutil.supportedprotocols)
1907 security = set(sslutil.supportedprotocols)
1908 if sslutil.hassni:
1908 if sslutil.hassni:
1909 security.add('sni')
1909 security.add('sni')
1910
1910
1911 fm.write('pythonsecurity', _("checking Python security support (%s)\n"),
1911 fm.write('pythonsecurity', _("checking Python security support (%s)\n"),
1912 fm.formatlist(sorted(security), name='protocol',
1912 fm.formatlist(sorted(security), name='protocol',
1913 fmt='%s', sep=','))
1913 fmt='%s', sep=','))
1914
1914
1915 # These are warnings, not errors. So don't increment problem count. This
1915 # These are warnings, not errors. So don't increment problem count. This
1916 # may change in the future.
1916 # may change in the future.
1917 if 'tls1.2' not in security:
1917 if 'tls1.2' not in security:
1918 fm.plain(_(' TLS 1.2 not supported by Python install; '
1918 fm.plain(_(' TLS 1.2 not supported by Python install; '
1919 'network connections lack modern security\n'))
1919 'network connections lack modern security\n'))
1920 if 'sni' not in security:
1920 if 'sni' not in security:
1921 fm.plain(_(' SNI not supported by Python install; may have '
1921 fm.plain(_(' SNI not supported by Python install; may have '
1922 'connectivity issues with some servers\n'))
1922 'connectivity issues with some servers\n'))
1923
1923
1924 # TODO print CA cert info
1924 # TODO print CA cert info
1925
1925
1926 # hg version
1926 # hg version
1927 hgver = util.version()
1927 hgver = util.version()
1928 fm.write('hgver', _("checking Mercurial version (%s)\n"),
1928 fm.write('hgver', _("checking Mercurial version (%s)\n"),
1929 hgver.split('+')[0])
1929 hgver.split('+')[0])
1930 fm.write('hgverextra', _("checking Mercurial custom build (%s)\n"),
1930 fm.write('hgverextra', _("checking Mercurial custom build (%s)\n"),
1931 '+'.join(hgver.split('+')[1:]))
1931 '+'.join(hgver.split('+')[1:]))
1932
1932
1933 # compiled modules
1933 # compiled modules
1934 fm.write('hgmodulepolicy', _("checking module policy (%s)\n"),
1934 fm.write('hgmodulepolicy', _("checking module policy (%s)\n"),
1935 policy.policy)
1935 policy.policy)
1936 fm.write('hgmodules', _("checking installed modules (%s)...\n"),
1936 fm.write('hgmodules', _("checking installed modules (%s)...\n"),
1937 os.path.dirname(__file__))
1937 os.path.dirname(__file__))
1938
1938
1939 err = None
1939 err = None
1940 try:
1940 try:
1941 from . import (
1941 from . import (
1942 base85,
1942 base85,
1943 bdiff,
1943 bdiff,
1944 mpatch,
1944 mpatch,
1945 osutil,
1945 osutil,
1946 )
1946 )
1947 dir(bdiff), dir(mpatch), dir(base85), dir(osutil) # quiet pyflakes
1947 dir(bdiff), dir(mpatch), dir(base85), dir(osutil) # quiet pyflakes
1948 except Exception as inst:
1948 except Exception as inst:
1949 err = inst
1949 err = inst
1950 problems += 1
1950 problems += 1
1951 fm.condwrite(err, 'extensionserror', " %s\n", err)
1951 fm.condwrite(err, 'extensionserror', " %s\n", err)
1952
1952
1953 compengines = util.compengines._engines.values()
1953 compengines = util.compengines._engines.values()
1954 fm.write('compengines', _('checking registered compression engines (%s)\n'),
1954 fm.write('compengines', _('checking registered compression engines (%s)\n'),
1955 fm.formatlist(sorted(e.name() for e in compengines),
1955 fm.formatlist(sorted(e.name() for e in compengines),
1956 name='compengine', fmt='%s', sep=', '))
1956 name='compengine', fmt='%s', sep=', '))
1957 fm.write('compenginesavail', _('checking available compression engines '
1957 fm.write('compenginesavail', _('checking available compression engines '
1958 '(%s)\n'),
1958 '(%s)\n'),
1959 fm.formatlist(sorted(e.name() for e in compengines
1959 fm.formatlist(sorted(e.name() for e in compengines
1960 if e.available()),
1960 if e.available()),
1961 name='compengine', fmt='%s', sep=', '))
1961 name='compengine', fmt='%s', sep=', '))
1962 wirecompengines = util.compengines.supportedwireengines(util.SERVERROLE)
1962 wirecompengines = util.compengines.supportedwireengines(util.SERVERROLE)
1963 fm.write('compenginesserver', _('checking available compression engines '
1963 fm.write('compenginesserver', _('checking available compression engines '
1964 'for wire protocol (%s)\n'),
1964 'for wire protocol (%s)\n'),
1965 fm.formatlist([e.name() for e in wirecompengines
1965 fm.formatlist([e.name() for e in wirecompengines
1966 if e.wireprotosupport()],
1966 if e.wireprotosupport()],
1967 name='compengine', fmt='%s', sep=', '))
1967 name='compengine', fmt='%s', sep=', '))
1968
1968
1969 # templates
1969 # templates
1970 p = templater.templatepaths()
1970 p = templater.templatepaths()
1971 fm.write('templatedirs', 'checking templates (%s)...\n', ' '.join(p))
1971 fm.write('templatedirs', 'checking templates (%s)...\n', ' '.join(p))
1972 fm.condwrite(not p, '', _(" no template directories found\n"))
1972 fm.condwrite(not p, '', _(" no template directories found\n"))
1973 if p:
1973 if p:
1974 m = templater.templatepath("map-cmdline.default")
1974 m = templater.templatepath("map-cmdline.default")
1975 if m:
1975 if m:
1976 # template found, check if it is working
1976 # template found, check if it is working
1977 err = None
1977 err = None
1978 try:
1978 try:
1979 templater.templater.frommapfile(m)
1979 templater.templater.frommapfile(m)
1980 except Exception as inst:
1980 except Exception as inst:
1981 err = inst
1981 err = inst
1982 p = None
1982 p = None
1983 fm.condwrite(err, 'defaulttemplateerror', " %s\n", err)
1983 fm.condwrite(err, 'defaulttemplateerror', " %s\n", err)
1984 else:
1984 else:
1985 p = None
1985 p = None
1986 fm.condwrite(p, 'defaulttemplate',
1986 fm.condwrite(p, 'defaulttemplate',
1987 _("checking default template (%s)\n"), m)
1987 _("checking default template (%s)\n"), m)
1988 fm.condwrite(not m, 'defaulttemplatenotfound',
1988 fm.condwrite(not m, 'defaulttemplatenotfound',
1989 _(" template '%s' not found\n"), "default")
1989 _(" template '%s' not found\n"), "default")
1990 if not p:
1990 if not p:
1991 problems += 1
1991 problems += 1
1992 fm.condwrite(not p, '',
1992 fm.condwrite(not p, '',
1993 _(" (templates seem to have been installed incorrectly)\n"))
1993 _(" (templates seem to have been installed incorrectly)\n"))
1994
1994
1995 # editor
1995 # editor
1996 editor = ui.geteditor()
1996 editor = ui.geteditor()
1997 editor = util.expandpath(editor)
1997 editor = util.expandpath(editor)
1998 fm.write('editor', _("checking commit editor... (%s)\n"), editor)
1998 fm.write('editor', _("checking commit editor... (%s)\n"), editor)
1999 cmdpath = util.findexe(pycompat.shlexsplit(editor)[0])
1999 cmdpath = util.findexe(pycompat.shlexsplit(editor)[0])
2000 fm.condwrite(not cmdpath and editor == 'vi', 'vinotfound',
2000 fm.condwrite(not cmdpath and editor == 'vi', 'vinotfound',
2001 _(" No commit editor set and can't find %s in PATH\n"
2001 _(" No commit editor set and can't find %s in PATH\n"
2002 " (specify a commit editor in your configuration"
2002 " (specify a commit editor in your configuration"
2003 " file)\n"), not cmdpath and editor == 'vi' and editor)
2003 " file)\n"), not cmdpath and editor == 'vi' and editor)
2004 fm.condwrite(not cmdpath and editor != 'vi', 'editornotfound',
2004 fm.condwrite(not cmdpath and editor != 'vi', 'editornotfound',
2005 _(" Can't find editor '%s' in PATH\n"
2005 _(" Can't find editor '%s' in PATH\n"
2006 " (specify a commit editor in your configuration"
2006 " (specify a commit editor in your configuration"
2007 " file)\n"), not cmdpath and editor)
2007 " file)\n"), not cmdpath and editor)
2008 if not cmdpath and editor != 'vi':
2008 if not cmdpath and editor != 'vi':
2009 problems += 1
2009 problems += 1
2010
2010
2011 # check username
2011 # check username
2012 username = None
2012 username = None
2013 err = None
2013 err = None
2014 try:
2014 try:
2015 username = ui.username()
2015 username = ui.username()
2016 except error.Abort as e:
2016 except error.Abort as e:
2017 err = e
2017 err = e
2018 problems += 1
2018 problems += 1
2019
2019
2020 fm.condwrite(username, 'username', _("checking username (%s)\n"), username)
2020 fm.condwrite(username, 'username', _("checking username (%s)\n"), username)
2021 fm.condwrite(err, 'usernameerror', _("checking username...\n %s\n"
2021 fm.condwrite(err, 'usernameerror', _("checking username...\n %s\n"
2022 " (specify a username in your configuration file)\n"), err)
2022 " (specify a username in your configuration file)\n"), err)
2023
2023
2024 fm.condwrite(not problems, '',
2024 fm.condwrite(not problems, '',
2025 _("no problems detected\n"))
2025 _("no problems detected\n"))
2026 if not problems:
2026 if not problems:
2027 fm.data(problems=problems)
2027 fm.data(problems=problems)
2028 fm.condwrite(problems, 'problems',
2028 fm.condwrite(problems, 'problems',
2029 _("%d problems detected,"
2029 _("%d problems detected,"
2030 " please check your install!\n"), problems)
2030 " please check your install!\n"), problems)
2031 fm.end()
2031 fm.end()
2032
2032
2033 return problems
2033 return problems
2034
2034
2035 @command('debugknown', [], _('REPO ID...'), norepo=True)
2035 @command('debugknown', [], _('REPO ID...'), norepo=True)
2036 def debugknown(ui, repopath, *ids, **opts):
2036 def debugknown(ui, repopath, *ids, **opts):
2037 """test whether node ids are known to a repo
2037 """test whether node ids are known to a repo
2038
2038
2039 Every ID must be a full-length hex node id string. Returns a list of 0s
2039 Every ID must be a full-length hex node id string. Returns a list of 0s
2040 and 1s indicating unknown/known.
2040 and 1s indicating unknown/known.
2041 """
2041 """
2042 repo = hg.peer(ui, opts, repopath)
2042 repo = hg.peer(ui, opts, repopath)
2043 if not repo.capable('known'):
2043 if not repo.capable('known'):
2044 raise error.Abort("known() not supported by target repository")
2044 raise error.Abort("known() not supported by target repository")
2045 flags = repo.known([bin(s) for s in ids])
2045 flags = repo.known([bin(s) for s in ids])
2046 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
2046 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
2047
2047
2048 @command('debuglabelcomplete', [], _('LABEL...'))
2048 @command('debuglabelcomplete', [], _('LABEL...'))
2049 def debuglabelcomplete(ui, repo, *args):
2049 def debuglabelcomplete(ui, repo, *args):
2050 '''backwards compatibility with old bash completion scripts (DEPRECATED)'''
2050 '''backwards compatibility with old bash completion scripts (DEPRECATED)'''
2051 debugnamecomplete(ui, repo, *args)
2051 debugnamecomplete(ui, repo, *args)
2052
2052
2053 @command('debugmergestate', [], '')
2053 @command('debugmergestate', [], '')
2054 def debugmergestate(ui, repo, *args):
2054 def debugmergestate(ui, repo, *args):
2055 """print merge state
2055 """print merge state
2056
2056
2057 Use --verbose to print out information about whether v1 or v2 merge state
2057 Use --verbose to print out information about whether v1 or v2 merge state
2058 was chosen."""
2058 was chosen."""
2059 def _hashornull(h):
2059 def _hashornull(h):
2060 if h == nullhex:
2060 if h == nullhex:
2061 return 'null'
2061 return 'null'
2062 else:
2062 else:
2063 return h
2063 return h
2064
2064
2065 def printrecords(version):
2065 def printrecords(version):
2066 ui.write(('* version %s records\n') % version)
2066 ui.write(('* version %s records\n') % version)
2067 if version == 1:
2067 if version == 1:
2068 records = v1records
2068 records = v1records
2069 else:
2069 else:
2070 records = v2records
2070 records = v2records
2071
2071
2072 for rtype, record in records:
2072 for rtype, record in records:
2073 # pretty print some record types
2073 # pretty print some record types
2074 if rtype == 'L':
2074 if rtype == 'L':
2075 ui.write(('local: %s\n') % record)
2075 ui.write(('local: %s\n') % record)
2076 elif rtype == 'O':
2076 elif rtype == 'O':
2077 ui.write(('other: %s\n') % record)
2077 ui.write(('other: %s\n') % record)
2078 elif rtype == 'm':
2078 elif rtype == 'm':
2079 driver, mdstate = record.split('\0', 1)
2079 driver, mdstate = record.split('\0', 1)
2080 ui.write(('merge driver: %s (state "%s")\n')
2080 ui.write(('merge driver: %s (state "%s")\n')
2081 % (driver, mdstate))
2081 % (driver, mdstate))
2082 elif rtype in 'FDC':
2082 elif rtype in 'FDC':
2083 r = record.split('\0')
2083 r = record.split('\0')
2084 f, state, hash, lfile, afile, anode, ofile = r[0:7]
2084 f, state, hash, lfile, afile, anode, ofile = r[0:7]
2085 if version == 1:
2085 if version == 1:
2086 onode = 'not stored in v1 format'
2086 onode = 'not stored in v1 format'
2087 flags = r[7]
2087 flags = r[7]
2088 else:
2088 else:
2089 onode, flags = r[7:9]
2089 onode, flags = r[7:9]
2090 ui.write(('file: %s (record type "%s", state "%s", hash %s)\n')
2090 ui.write(('file: %s (record type "%s", state "%s", hash %s)\n')
2091 % (f, rtype, state, _hashornull(hash)))
2091 % (f, rtype, state, _hashornull(hash)))
2092 ui.write((' local path: %s (flags "%s")\n') % (lfile, flags))
2092 ui.write((' local path: %s (flags "%s")\n') % (lfile, flags))
2093 ui.write((' ancestor path: %s (node %s)\n')
2093 ui.write((' ancestor path: %s (node %s)\n')
2094 % (afile, _hashornull(anode)))
2094 % (afile, _hashornull(anode)))
2095 ui.write((' other path: %s (node %s)\n')
2095 ui.write((' other path: %s (node %s)\n')
2096 % (ofile, _hashornull(onode)))
2096 % (ofile, _hashornull(onode)))
2097 elif rtype == 'f':
2097 elif rtype == 'f':
2098 filename, rawextras = record.split('\0', 1)
2098 filename, rawextras = record.split('\0', 1)
2099 extras = rawextras.split('\0')
2099 extras = rawextras.split('\0')
2100 i = 0
2100 i = 0
2101 extrastrings = []
2101 extrastrings = []
2102 while i < len(extras):
2102 while i < len(extras):
2103 extrastrings.append('%s = %s' % (extras[i], extras[i + 1]))
2103 extrastrings.append('%s = %s' % (extras[i], extras[i + 1]))
2104 i += 2
2104 i += 2
2105
2105
2106 ui.write(('file extras: %s (%s)\n')
2106 ui.write(('file extras: %s (%s)\n')
2107 % (filename, ', '.join(extrastrings)))
2107 % (filename, ', '.join(extrastrings)))
2108 elif rtype == 'l':
2108 elif rtype == 'l':
2109 labels = record.split('\0', 2)
2109 labels = record.split('\0', 2)
2110 labels = [l for l in labels if len(l) > 0]
2110 labels = [l for l in labels if len(l) > 0]
2111 ui.write(('labels:\n'))
2111 ui.write(('labels:\n'))
2112 ui.write((' local: %s\n' % labels[0]))
2112 ui.write((' local: %s\n' % labels[0]))
2113 ui.write((' other: %s\n' % labels[1]))
2113 ui.write((' other: %s\n' % labels[1]))
2114 if len(labels) > 2:
2114 if len(labels) > 2:
2115 ui.write((' base: %s\n' % labels[2]))
2115 ui.write((' base: %s\n' % labels[2]))
2116 else:
2116 else:
2117 ui.write(('unrecognized entry: %s\t%s\n')
2117 ui.write(('unrecognized entry: %s\t%s\n')
2118 % (rtype, record.replace('\0', '\t')))
2118 % (rtype, record.replace('\0', '\t')))
2119
2119
2120 # Avoid mergestate.read() since it may raise an exception for unsupported
2120 # Avoid mergestate.read() since it may raise an exception for unsupported
2121 # merge state records. We shouldn't be doing this, but this is OK since this
2121 # merge state records. We shouldn't be doing this, but this is OK since this
2122 # command is pretty low-level.
2122 # command is pretty low-level.
2123 ms = mergemod.mergestate(repo)
2123 ms = mergemod.mergestate(repo)
2124
2124
2125 # sort so that reasonable information is on top
2125 # sort so that reasonable information is on top
2126 v1records = ms._readrecordsv1()
2126 v1records = ms._readrecordsv1()
2127 v2records = ms._readrecordsv2()
2127 v2records = ms._readrecordsv2()
2128 order = 'LOml'
2128 order = 'LOml'
2129 def key(r):
2129 def key(r):
2130 idx = order.find(r[0])
2130 idx = order.find(r[0])
2131 if idx == -1:
2131 if idx == -1:
2132 return (1, r[1])
2132 return (1, r[1])
2133 else:
2133 else:
2134 return (0, idx)
2134 return (0, idx)
2135 v1records.sort(key=key)
2135 v1records.sort(key=key)
2136 v2records.sort(key=key)
2136 v2records.sort(key=key)
2137
2137
2138 if not v1records and not v2records:
2138 if not v1records and not v2records:
2139 ui.write(('no merge state found\n'))
2139 ui.write(('no merge state found\n'))
2140 elif not v2records:
2140 elif not v2records:
2141 ui.note(('no version 2 merge state\n'))
2141 ui.note(('no version 2 merge state\n'))
2142 printrecords(1)
2142 printrecords(1)
2143 elif ms._v1v2match(v1records, v2records):
2143 elif ms._v1v2match(v1records, v2records):
2144 ui.note(('v1 and v2 states match: using v2\n'))
2144 ui.note(('v1 and v2 states match: using v2\n'))
2145 printrecords(2)
2145 printrecords(2)
2146 else:
2146 else:
2147 ui.note(('v1 and v2 states mismatch: using v1\n'))
2147 ui.note(('v1 and v2 states mismatch: using v1\n'))
2148 printrecords(1)
2148 printrecords(1)
2149 if ui.verbose:
2149 if ui.verbose:
2150 printrecords(2)
2150 printrecords(2)
2151
2151
2152 @command('debugnamecomplete', [], _('NAME...'))
2152 @command('debugnamecomplete', [], _('NAME...'))
2153 def debugnamecomplete(ui, repo, *args):
2153 def debugnamecomplete(ui, repo, *args):
2154 '''complete "names" - tags, open branch names, bookmark names'''
2154 '''complete "names" - tags, open branch names, bookmark names'''
2155
2155
2156 names = set()
2156 names = set()
2157 # since we previously only listed open branches, we will handle that
2157 # since we previously only listed open branches, we will handle that
2158 # specially (after this for loop)
2158 # specially (after this for loop)
2159 for name, ns in repo.names.iteritems():
2159 for name, ns in repo.names.iteritems():
2160 if name != 'branches':
2160 if name != 'branches':
2161 names.update(ns.listnames(repo))
2161 names.update(ns.listnames(repo))
2162 names.update(tag for (tag, heads, tip, closed)
2162 names.update(tag for (tag, heads, tip, closed)
2163 in repo.branchmap().iterbranches() if not closed)
2163 in repo.branchmap().iterbranches() if not closed)
2164 completions = set()
2164 completions = set()
2165 if not args:
2165 if not args:
2166 args = ['']
2166 args = ['']
2167 for a in args:
2167 for a in args:
2168 completions.update(n for n in names if n.startswith(a))
2168 completions.update(n for n in names if n.startswith(a))
2169 ui.write('\n'.join(sorted(completions)))
2169 ui.write('\n'.join(sorted(completions)))
2170 ui.write('\n')
2170 ui.write('\n')
2171
2171
2172 @command('debuglocks',
2172 @command('debuglocks',
2173 [('L', 'force-lock', None, _('free the store lock (DANGEROUS)')),
2173 [('L', 'force-lock', None, _('free the store lock (DANGEROUS)')),
2174 ('W', 'force-wlock', None,
2174 ('W', 'force-wlock', None,
2175 _('free the working state lock (DANGEROUS)'))],
2175 _('free the working state lock (DANGEROUS)'))],
2176 _('[OPTION]...'))
2176 _('[OPTION]...'))
2177 def debuglocks(ui, repo, **opts):
2177 def debuglocks(ui, repo, **opts):
2178 """show or modify state of locks
2178 """show or modify state of locks
2179
2179
2180 By default, this command will show which locks are held. This
2180 By default, this command will show which locks are held. This
2181 includes the user and process holding the lock, the amount of time
2181 includes the user and process holding the lock, the amount of time
2182 the lock has been held, and the machine name where the process is
2182 the lock has been held, and the machine name where the process is
2183 running if it's not local.
2183 running if it's not local.
2184
2184
2185 Locks protect the integrity of Mercurial's data, so should be
2185 Locks protect the integrity of Mercurial's data, so should be
2186 treated with care. System crashes or other interruptions may cause
2186 treated with care. System crashes or other interruptions may cause
2187 locks to not be properly released, though Mercurial will usually
2187 locks to not be properly released, though Mercurial will usually
2188 detect and remove such stale locks automatically.
2188 detect and remove such stale locks automatically.
2189
2189
2190 However, detecting stale locks may not always be possible (for
2190 However, detecting stale locks may not always be possible (for
2191 instance, on a shared filesystem). Removing locks may also be
2191 instance, on a shared filesystem). Removing locks may also be
2192 blocked by filesystem permissions.
2192 blocked by filesystem permissions.
2193
2193
2194 Returns 0 if no locks are held.
2194 Returns 0 if no locks are held.
2195
2195
2196 """
2196 """
2197
2197
2198 if opts.get('force_lock'):
2198 if opts.get('force_lock'):
2199 repo.svfs.unlink('lock')
2199 repo.svfs.unlink('lock')
2200 if opts.get('force_wlock'):
2200 if opts.get('force_wlock'):
2201 repo.vfs.unlink('wlock')
2201 repo.vfs.unlink('wlock')
2202 if opts.get('force_lock') or opts.get('force_lock'):
2202 if opts.get('force_lock') or opts.get('force_lock'):
2203 return 0
2203 return 0
2204
2204
2205 now = time.time()
2205 now = time.time()
2206 held = 0
2206 held = 0
2207
2207
2208 def report(vfs, name, method):
2208 def report(vfs, name, method):
2209 # this causes stale locks to get reaped for more accurate reporting
2209 # this causes stale locks to get reaped for more accurate reporting
2210 try:
2210 try:
2211 l = method(False)
2211 l = method(False)
2212 except error.LockHeld:
2212 except error.LockHeld:
2213 l = None
2213 l = None
2214
2214
2215 if l:
2215 if l:
2216 l.release()
2216 l.release()
2217 else:
2217 else:
2218 try:
2218 try:
2219 stat = vfs.lstat(name)
2219 stat = vfs.lstat(name)
2220 age = now - stat.st_mtime
2220 age = now - stat.st_mtime
2221 user = util.username(stat.st_uid)
2221 user = util.username(stat.st_uid)
2222 locker = vfs.readlock(name)
2222 locker = vfs.readlock(name)
2223 if ":" in locker:
2223 if ":" in locker:
2224 host, pid = locker.split(':')
2224 host, pid = locker.split(':')
2225 if host == socket.gethostname():
2225 if host == socket.gethostname():
2226 locker = 'user %s, process %s' % (user, pid)
2226 locker = 'user %s, process %s' % (user, pid)
2227 else:
2227 else:
2228 locker = 'user %s, process %s, host %s' \
2228 locker = 'user %s, process %s, host %s' \
2229 % (user, pid, host)
2229 % (user, pid, host)
2230 ui.write(("%-6s %s (%ds)\n") % (name + ":", locker, age))
2230 ui.write(("%-6s %s (%ds)\n") % (name + ":", locker, age))
2231 return 1
2231 return 1
2232 except OSError as e:
2232 except OSError as e:
2233 if e.errno != errno.ENOENT:
2233 if e.errno != errno.ENOENT:
2234 raise
2234 raise
2235
2235
2236 ui.write(("%-6s free\n") % (name + ":"))
2236 ui.write(("%-6s free\n") % (name + ":"))
2237 return 0
2237 return 0
2238
2238
2239 held += report(repo.svfs, "lock", repo.lock)
2239 held += report(repo.svfs, "lock", repo.lock)
2240 held += report(repo.vfs, "wlock", repo.wlock)
2240 held += report(repo.vfs, "wlock", repo.wlock)
2241
2241
2242 return held
2242 return held
2243
2243
2244 @command('debugobsolete',
2244 @command('debugobsolete',
2245 [('', 'flags', 0, _('markers flag')),
2245 [('', 'flags', 0, _('markers flag')),
2246 ('', 'record-parents', False,
2246 ('', 'record-parents', False,
2247 _('record parent information for the precursor')),
2247 _('record parent information for the precursor')),
2248 ('r', 'rev', [], _('display markers relevant to REV')),
2248 ('r', 'rev', [], _('display markers relevant to REV')),
2249 ('', 'index', False, _('display index of the marker')),
2249 ('', 'index', False, _('display index of the marker')),
2250 ('', 'delete', [], _('delete markers specified by indices')),
2250 ('', 'delete', [], _('delete markers specified by indices')),
2251 ] + commitopts2 + formatteropts,
2251 ] + commitopts2 + formatteropts,
2252 _('[OBSOLETED [REPLACEMENT ...]]'))
2252 _('[OBSOLETED [REPLACEMENT ...]]'))
2253 def debugobsolete(ui, repo, precursor=None, *successors, **opts):
2253 def debugobsolete(ui, repo, precursor=None, *successors, **opts):
2254 """create arbitrary obsolete marker
2254 """create arbitrary obsolete marker
2255
2255
2256 With no arguments, displays the list of obsolescence markers."""
2256 With no arguments, displays the list of obsolescence markers."""
2257
2257
2258 def parsenodeid(s):
2258 def parsenodeid(s):
2259 try:
2259 try:
2260 # We do not use revsingle/revrange functions here to accept
2260 # We do not use revsingle/revrange functions here to accept
2261 # arbitrary node identifiers, possibly not present in the
2261 # arbitrary node identifiers, possibly not present in the
2262 # local repository.
2262 # local repository.
2263 n = bin(s)
2263 n = bin(s)
2264 if len(n) != len(nullid):
2264 if len(n) != len(nullid):
2265 raise TypeError()
2265 raise TypeError()
2266 return n
2266 return n
2267 except TypeError:
2267 except TypeError:
2268 raise error.Abort('changeset references must be full hexadecimal '
2268 raise error.Abort('changeset references must be full hexadecimal '
2269 'node identifiers')
2269 'node identifiers')
2270
2270
2271 if opts.get('delete'):
2271 if opts.get('delete'):
2272 indices = []
2272 indices = []
2273 for v in opts.get('delete'):
2273 for v in opts.get('delete'):
2274 try:
2274 try:
2275 indices.append(int(v))
2275 indices.append(int(v))
2276 except ValueError:
2276 except ValueError:
2277 raise error.Abort(_('invalid index value: %r') % v,
2277 raise error.Abort(_('invalid index value: %r') % v,
2278 hint=_('use integers for indices'))
2278 hint=_('use integers for indices'))
2279
2279
2280 if repo.currenttransaction():
2280 if repo.currenttransaction():
2281 raise error.Abort(_('cannot delete obsmarkers in the middle '
2281 raise error.Abort(_('cannot delete obsmarkers in the middle '
2282 'of transaction.'))
2282 'of transaction.'))
2283
2283
2284 with repo.lock():
2284 with repo.lock():
2285 n = repair.deleteobsmarkers(repo.obsstore, indices)
2285 n = repair.deleteobsmarkers(repo.obsstore, indices)
2286 ui.write(_('deleted %i obsolescence markers\n') % n)
2286 ui.write(_('deleted %i obsolescence markers\n') % n)
2287
2287
2288 return
2288 return
2289
2289
2290 if precursor is not None:
2290 if precursor is not None:
2291 if opts['rev']:
2291 if opts['rev']:
2292 raise error.Abort('cannot select revision when creating marker')
2292 raise error.Abort('cannot select revision when creating marker')
2293 metadata = {}
2293 metadata = {}
2294 metadata['user'] = opts['user'] or ui.username()
2294 metadata['user'] = opts['user'] or ui.username()
2295 succs = tuple(parsenodeid(succ) for succ in successors)
2295 succs = tuple(parsenodeid(succ) for succ in successors)
2296 l = repo.lock()
2296 l = repo.lock()
2297 try:
2297 try:
2298 tr = repo.transaction('debugobsolete')
2298 tr = repo.transaction('debugobsolete')
2299 try:
2299 try:
2300 date = opts.get('date')
2300 date = opts.get('date')
2301 if date:
2301 if date:
2302 date = util.parsedate(date)
2302 date = util.parsedate(date)
2303 else:
2303 else:
2304 date = None
2304 date = None
2305 prec = parsenodeid(precursor)
2305 prec = parsenodeid(precursor)
2306 parents = None
2306 parents = None
2307 if opts['record_parents']:
2307 if opts['record_parents']:
2308 if prec not in repo.unfiltered():
2308 if prec not in repo.unfiltered():
2309 raise error.Abort('cannot used --record-parents on '
2309 raise error.Abort('cannot used --record-parents on '
2310 'unknown changesets')
2310 'unknown changesets')
2311 parents = repo.unfiltered()[prec].parents()
2311 parents = repo.unfiltered()[prec].parents()
2312 parents = tuple(p.node() for p in parents)
2312 parents = tuple(p.node() for p in parents)
2313 repo.obsstore.create(tr, prec, succs, opts['flags'],
2313 repo.obsstore.create(tr, prec, succs, opts['flags'],
2314 parents=parents, date=date,
2314 parents=parents, date=date,
2315 metadata=metadata)
2315 metadata=metadata)
2316 tr.close()
2316 tr.close()
2317 except ValueError as exc:
2317 except ValueError as exc:
2318 raise error.Abort(_('bad obsmarker input: %s') % exc)
2318 raise error.Abort(_('bad obsmarker input: %s') % exc)
2319 finally:
2319 finally:
2320 tr.release()
2320 tr.release()
2321 finally:
2321 finally:
2322 l.release()
2322 l.release()
2323 else:
2323 else:
2324 if opts['rev']:
2324 if opts['rev']:
2325 revs = scmutil.revrange(repo, opts['rev'])
2325 revs = scmutil.revrange(repo, opts['rev'])
2326 nodes = [repo[r].node() for r in revs]
2326 nodes = [repo[r].node() for r in revs]
2327 markers = list(obsolete.getmarkers(repo, nodes=nodes))
2327 markers = list(obsolete.getmarkers(repo, nodes=nodes))
2328 markers.sort(key=lambda x: x._data)
2328 markers.sort(key=lambda x: x._data)
2329 else:
2329 else:
2330 markers = obsolete.getmarkers(repo)
2330 markers = obsolete.getmarkers(repo)
2331
2331
2332 markerstoiter = markers
2332 markerstoiter = markers
2333 isrelevant = lambda m: True
2333 isrelevant = lambda m: True
2334 if opts.get('rev') and opts.get('index'):
2334 if opts.get('rev') and opts.get('index'):
2335 markerstoiter = obsolete.getmarkers(repo)
2335 markerstoiter = obsolete.getmarkers(repo)
2336 markerset = set(markers)
2336 markerset = set(markers)
2337 isrelevant = lambda m: m in markerset
2337 isrelevant = lambda m: m in markerset
2338
2338
2339 fm = ui.formatter('debugobsolete', opts)
2339 fm = ui.formatter('debugobsolete', opts)
2340 for i, m in enumerate(markerstoiter):
2340 for i, m in enumerate(markerstoiter):
2341 if not isrelevant(m):
2341 if not isrelevant(m):
2342 # marker can be irrelevant when we're iterating over a set
2342 # marker can be irrelevant when we're iterating over a set
2343 # of markers (markerstoiter) which is bigger than the set
2343 # of markers (markerstoiter) which is bigger than the set
2344 # of markers we want to display (markers)
2344 # of markers we want to display (markers)
2345 # this can happen if both --index and --rev options are
2345 # this can happen if both --index and --rev options are
2346 # provided and thus we need to iterate over all of the markers
2346 # provided and thus we need to iterate over all of the markers
2347 # to get the correct indices, but only display the ones that
2347 # to get the correct indices, but only display the ones that
2348 # are relevant to --rev value
2348 # are relevant to --rev value
2349 continue
2349 continue
2350 fm.startitem()
2350 fm.startitem()
2351 ind = i if opts.get('index') else None
2351 ind = i if opts.get('index') else None
2352 cmdutil.showmarker(fm, m, index=ind)
2352 cmdutil.showmarker(fm, m, index=ind)
2353 fm.end()
2353 fm.end()
2354
2354
2355 @command('debugpathcomplete',
2355 @command('debugpathcomplete',
2356 [('f', 'full', None, _('complete an entire path')),
2356 [('f', 'full', None, _('complete an entire path')),
2357 ('n', 'normal', None, _('show only normal files')),
2357 ('n', 'normal', None, _('show only normal files')),
2358 ('a', 'added', None, _('show only added files')),
2358 ('a', 'added', None, _('show only added files')),
2359 ('r', 'removed', None, _('show only removed files'))],
2359 ('r', 'removed', None, _('show only removed files'))],
2360 _('FILESPEC...'))
2360 _('FILESPEC...'))
2361 def debugpathcomplete(ui, repo, *specs, **opts):
2361 def debugpathcomplete(ui, repo, *specs, **opts):
2362 '''complete part or all of a tracked path
2362 '''complete part or all of a tracked path
2363
2363
2364 This command supports shells that offer path name completion. It
2364 This command supports shells that offer path name completion. It
2365 currently completes only files already known to the dirstate.
2365 currently completes only files already known to the dirstate.
2366
2366
2367 Completion extends only to the next path segment unless
2367 Completion extends only to the next path segment unless
2368 --full is specified, in which case entire paths are used.'''
2368 --full is specified, in which case entire paths are used.'''
2369
2369
2370 def complete(path, acceptable):
2370 def complete(path, acceptable):
2371 dirstate = repo.dirstate
2371 dirstate = repo.dirstate
2372 spec = os.path.normpath(os.path.join(pycompat.getcwd(), path))
2372 spec = os.path.normpath(os.path.join(pycompat.getcwd(), path))
2373 rootdir = repo.root + pycompat.ossep
2373 rootdir = repo.root + pycompat.ossep
2374 if spec != repo.root and not spec.startswith(rootdir):
2374 if spec != repo.root and not spec.startswith(rootdir):
2375 return [], []
2375 return [], []
2376 if os.path.isdir(spec):
2376 if os.path.isdir(spec):
2377 spec += '/'
2377 spec += '/'
2378 spec = spec[len(rootdir):]
2378 spec = spec[len(rootdir):]
2379 fixpaths = pycompat.ossep != '/'
2379 fixpaths = pycompat.ossep != '/'
2380 if fixpaths:
2380 if fixpaths:
2381 spec = spec.replace(pycompat.ossep, '/')
2381 spec = spec.replace(pycompat.ossep, '/')
2382 speclen = len(spec)
2382 speclen = len(spec)
2383 fullpaths = opts['full']
2383 fullpaths = opts['full']
2384 files, dirs = set(), set()
2384 files, dirs = set(), set()
2385 adddir, addfile = dirs.add, files.add
2385 adddir, addfile = dirs.add, files.add
2386 for f, st in dirstate.iteritems():
2386 for f, st in dirstate.iteritems():
2387 if f.startswith(spec) and st[0] in acceptable:
2387 if f.startswith(spec) and st[0] in acceptable:
2388 if fixpaths:
2388 if fixpaths:
2389 f = f.replace('/', pycompat.ossep)
2389 f = f.replace('/', pycompat.ossep)
2390 if fullpaths:
2390 if fullpaths:
2391 addfile(f)
2391 addfile(f)
2392 continue
2392 continue
2393 s = f.find(pycompat.ossep, speclen)
2393 s = f.find(pycompat.ossep, speclen)
2394 if s >= 0:
2394 if s >= 0:
2395 adddir(f[:s])
2395 adddir(f[:s])
2396 else:
2396 else:
2397 addfile(f)
2397 addfile(f)
2398 return files, dirs
2398 return files, dirs
2399
2399
2400 acceptable = ''
2400 acceptable = ''
2401 if opts['normal']:
2401 if opts['normal']:
2402 acceptable += 'nm'
2402 acceptable += 'nm'
2403 if opts['added']:
2403 if opts['added']:
2404 acceptable += 'a'
2404 acceptable += 'a'
2405 if opts['removed']:
2405 if opts['removed']:
2406 acceptable += 'r'
2406 acceptable += 'r'
2407 cwd = repo.getcwd()
2407 cwd = repo.getcwd()
2408 if not specs:
2408 if not specs:
2409 specs = ['.']
2409 specs = ['.']
2410
2410
2411 files, dirs = set(), set()
2411 files, dirs = set(), set()
2412 for spec in specs:
2412 for spec in specs:
2413 f, d = complete(spec, acceptable or 'nmar')
2413 f, d = complete(spec, acceptable or 'nmar')
2414 files.update(f)
2414 files.update(f)
2415 dirs.update(d)
2415 dirs.update(d)
2416 files.update(dirs)
2416 files.update(dirs)
2417 ui.write('\n'.join(repo.pathto(p, cwd) for p in sorted(files)))
2417 ui.write('\n'.join(repo.pathto(p, cwd) for p in sorted(files)))
2418 ui.write('\n')
2418 ui.write('\n')
2419
2419
2420 @command('debugpushkey', [], _('REPO NAMESPACE [KEY OLD NEW]'), norepo=True)
2420 @command('debugpushkey', [], _('REPO NAMESPACE [KEY OLD NEW]'), norepo=True)
2421 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
2421 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
2422 '''access the pushkey key/value protocol
2422 '''access the pushkey key/value protocol
2423
2423
2424 With two args, list the keys in the given namespace.
2424 With two args, list the keys in the given namespace.
2425
2425
2426 With five args, set a key to new if it currently is set to old.
2426 With five args, set a key to new if it currently is set to old.
2427 Reports success or failure.
2427 Reports success or failure.
2428 '''
2428 '''
2429
2429
2430 target = hg.peer(ui, {}, repopath)
2430 target = hg.peer(ui, {}, repopath)
2431 if keyinfo:
2431 if keyinfo:
2432 key, old, new = keyinfo
2432 key, old, new = keyinfo
2433 r = target.pushkey(namespace, key, old, new)
2433 r = target.pushkey(namespace, key, old, new)
2434 ui.status(str(r) + '\n')
2434 ui.status(str(r) + '\n')
2435 return not r
2435 return not r
2436 else:
2436 else:
2437 for k, v in sorted(target.listkeys(namespace).iteritems()):
2437 for k, v in sorted(target.listkeys(namespace).iteritems()):
2438 ui.write("%s\t%s\n" % (k.encode('string-escape'),
2438 ui.write("%s\t%s\n" % (k.encode('string-escape'),
2439 v.encode('string-escape')))
2439 v.encode('string-escape')))
2440
2440
2441 @command('debugpvec', [], _('A B'))
2441 @command('debugpvec', [], _('A B'))
2442 def debugpvec(ui, repo, a, b=None):
2442 def debugpvec(ui, repo, a, b=None):
2443 ca = scmutil.revsingle(repo, a)
2443 ca = scmutil.revsingle(repo, a)
2444 cb = scmutil.revsingle(repo, b)
2444 cb = scmutil.revsingle(repo, b)
2445 pa = pvec.ctxpvec(ca)
2445 pa = pvec.ctxpvec(ca)
2446 pb = pvec.ctxpvec(cb)
2446 pb = pvec.ctxpvec(cb)
2447 if pa == pb:
2447 if pa == pb:
2448 rel = "="
2448 rel = "="
2449 elif pa > pb:
2449 elif pa > pb:
2450 rel = ">"
2450 rel = ">"
2451 elif pa < pb:
2451 elif pa < pb:
2452 rel = "<"
2452 rel = "<"
2453 elif pa | pb:
2453 elif pa | pb:
2454 rel = "|"
2454 rel = "|"
2455 ui.write(_("a: %s\n") % pa)
2455 ui.write(_("a: %s\n") % pa)
2456 ui.write(_("b: %s\n") % pb)
2456 ui.write(_("b: %s\n") % pb)
2457 ui.write(_("depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth))
2457 ui.write(_("depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth))
2458 ui.write(_("delta: %d hdist: %d distance: %d relation: %s\n") %
2458 ui.write(_("delta: %d hdist: %d distance: %d relation: %s\n") %
2459 (abs(pa._depth - pb._depth), pvec._hamming(pa._vec, pb._vec),
2459 (abs(pa._depth - pb._depth), pvec._hamming(pa._vec, pb._vec),
2460 pa.distance(pb), rel))
2460 pa.distance(pb), rel))
2461
2461
2462 @command('debugrebuilddirstate|debugrebuildstate',
2462 @command('debugrebuilddirstate|debugrebuildstate',
2463 [('r', 'rev', '', _('revision to rebuild to'), _('REV')),
2463 [('r', 'rev', '', _('revision to rebuild to'), _('REV')),
2464 ('', 'minimal', None, _('only rebuild files that are inconsistent with '
2464 ('', 'minimal', None, _('only rebuild files that are inconsistent with '
2465 'the working copy parent')),
2465 'the working copy parent')),
2466 ],
2466 ],
2467 _('[-r REV]'))
2467 _('[-r REV]'))
2468 def debugrebuilddirstate(ui, repo, rev, **opts):
2468 def debugrebuilddirstate(ui, repo, rev, **opts):
2469 """rebuild the dirstate as it would look like for the given revision
2469 """rebuild the dirstate as it would look like for the given revision
2470
2470
2471 If no revision is specified the first current parent will be used.
2471 If no revision is specified the first current parent will be used.
2472
2472
2473 The dirstate will be set to the files of the given revision.
2473 The dirstate will be set to the files of the given revision.
2474 The actual working directory content or existing dirstate
2474 The actual working directory content or existing dirstate
2475 information such as adds or removes is not considered.
2475 information such as adds or removes is not considered.
2476
2476
2477 ``minimal`` will only rebuild the dirstate status for files that claim to be
2477 ``minimal`` will only rebuild the dirstate status for files that claim to be
2478 tracked but are not in the parent manifest, or that exist in the parent
2478 tracked but are not in the parent manifest, or that exist in the parent
2479 manifest but are not in the dirstate. It will not change adds, removes, or
2479 manifest but are not in the dirstate. It will not change adds, removes, or
2480 modified files that are in the working copy parent.
2480 modified files that are in the working copy parent.
2481
2481
2482 One use of this command is to make the next :hg:`status` invocation
2482 One use of this command is to make the next :hg:`status` invocation
2483 check the actual file content.
2483 check the actual file content.
2484 """
2484 """
2485 ctx = scmutil.revsingle(repo, rev)
2485 ctx = scmutil.revsingle(repo, rev)
2486 with repo.wlock():
2486 with repo.wlock():
2487 dirstate = repo.dirstate
2487 dirstate = repo.dirstate
2488 changedfiles = None
2488 changedfiles = None
2489 # See command doc for what minimal does.
2489 # See command doc for what minimal does.
2490 if opts.get('minimal'):
2490 if opts.get('minimal'):
2491 manifestfiles = set(ctx.manifest().keys())
2491 manifestfiles = set(ctx.manifest().keys())
2492 dirstatefiles = set(dirstate)
2492 dirstatefiles = set(dirstate)
2493 manifestonly = manifestfiles - dirstatefiles
2493 manifestonly = manifestfiles - dirstatefiles
2494 dsonly = dirstatefiles - manifestfiles
2494 dsonly = dirstatefiles - manifestfiles
2495 dsnotadded = set(f for f in dsonly if dirstate[f] != 'a')
2495 dsnotadded = set(f for f in dsonly if dirstate[f] != 'a')
2496 changedfiles = manifestonly | dsnotadded
2496 changedfiles = manifestonly | dsnotadded
2497
2497
2498 dirstate.rebuild(ctx.node(), ctx.manifest(), changedfiles)
2498 dirstate.rebuild(ctx.node(), ctx.manifest(), changedfiles)
2499
2499
2500 @command('debugrebuildfncache', [], '')
2500 @command('debugrebuildfncache', [], '')
2501 def debugrebuildfncache(ui, repo):
2501 def debugrebuildfncache(ui, repo):
2502 """rebuild the fncache file"""
2502 """rebuild the fncache file"""
2503 repair.rebuildfncache(ui, repo)
2503 repair.rebuildfncache(ui, repo)
2504
2504
2505 @command('debugrename',
2505 @command('debugrename',
2506 [('r', 'rev', '', _('revision to debug'), _('REV'))],
2506 [('r', 'rev', '', _('revision to debug'), _('REV'))],
2507 _('[-r REV] FILE'))
2507 _('[-r REV] FILE'))
2508 def debugrename(ui, repo, file1, *pats, **opts):
2508 def debugrename(ui, repo, file1, *pats, **opts):
2509 """dump rename information"""
2509 """dump rename information"""
2510
2510
2511 ctx = scmutil.revsingle(repo, opts.get('rev'))
2511 ctx = scmutil.revsingle(repo, opts.get('rev'))
2512 m = scmutil.match(ctx, (file1,) + pats, opts)
2512 m = scmutil.match(ctx, (file1,) + pats, opts)
2513 for abs in ctx.walk(m):
2513 for abs in ctx.walk(m):
2514 fctx = ctx[abs]
2514 fctx = ctx[abs]
2515 o = fctx.filelog().renamed(fctx.filenode())
2515 o = fctx.filelog().renamed(fctx.filenode())
2516 rel = m.rel(abs)
2516 rel = m.rel(abs)
2517 if o:
2517 if o:
2518 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
2518 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
2519 else:
2519 else:
2520 ui.write(_("%s not renamed\n") % rel)
2520 ui.write(_("%s not renamed\n") % rel)
2521
2521
2522 @command('debugrevlog', debugrevlogopts +
2522 @command('debugrevlog', debugrevlogopts +
2523 [('d', 'dump', False, _('dump index data'))],
2523 [('d', 'dump', False, _('dump index data'))],
2524 _('-c|-m|FILE'),
2524 _('-c|-m|FILE'),
2525 optionalrepo=True)
2525 optionalrepo=True)
2526 def debugrevlog(ui, repo, file_=None, **opts):
2526 def debugrevlog(ui, repo, file_=None, **opts):
2527 """show data and statistics about a revlog"""
2527 """show data and statistics about a revlog"""
2528 r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
2528 r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
2529
2529
2530 if opts.get("dump"):
2530 if opts.get("dump"):
2531 numrevs = len(r)
2531 numrevs = len(r)
2532 ui.write(("# rev p1rev p2rev start end deltastart base p1 p2"
2532 ui.write(("# rev p1rev p2rev start end deltastart base p1 p2"
2533 " rawsize totalsize compression heads chainlen\n"))
2533 " rawsize totalsize compression heads chainlen\n"))
2534 ts = 0
2534 ts = 0
2535 heads = set()
2535 heads = set()
2536
2536
2537 for rev in xrange(numrevs):
2537 for rev in xrange(numrevs):
2538 dbase = r.deltaparent(rev)
2538 dbase = r.deltaparent(rev)
2539 if dbase == -1:
2539 if dbase == -1:
2540 dbase = rev
2540 dbase = rev
2541 cbase = r.chainbase(rev)
2541 cbase = r.chainbase(rev)
2542 clen = r.chainlen(rev)
2542 clen = r.chainlen(rev)
2543 p1, p2 = r.parentrevs(rev)
2543 p1, p2 = r.parentrevs(rev)
2544 rs = r.rawsize(rev)
2544 rs = r.rawsize(rev)
2545 ts = ts + rs
2545 ts = ts + rs
2546 heads -= set(r.parentrevs(rev))
2546 heads -= set(r.parentrevs(rev))
2547 heads.add(rev)
2547 heads.add(rev)
2548 try:
2548 try:
2549 compression = ts / r.end(rev)
2549 compression = ts / r.end(rev)
2550 except ZeroDivisionError:
2550 except ZeroDivisionError:
2551 compression = 0
2551 compression = 0
2552 ui.write("%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
2552 ui.write("%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
2553 "%11d %5d %8d\n" %
2553 "%11d %5d %8d\n" %
2554 (rev, p1, p2, r.start(rev), r.end(rev),
2554 (rev, p1, p2, r.start(rev), r.end(rev),
2555 r.start(dbase), r.start(cbase),
2555 r.start(dbase), r.start(cbase),
2556 r.start(p1), r.start(p2),
2556 r.start(p1), r.start(p2),
2557 rs, ts, compression, len(heads), clen))
2557 rs, ts, compression, len(heads), clen))
2558 return 0
2558 return 0
2559
2559
2560 v = r.version
2560 v = r.version
2561 format = v & 0xFFFF
2561 format = v & 0xFFFF
2562 flags = []
2562 flags = []
2563 gdelta = False
2563 gdelta = False
2564 if v & revlog.REVLOGNGINLINEDATA:
2564 if v & revlog.REVLOGNGINLINEDATA:
2565 flags.append('inline')
2565 flags.append('inline')
2566 if v & revlog.REVLOGGENERALDELTA:
2566 if v & revlog.REVLOGGENERALDELTA:
2567 gdelta = True
2567 gdelta = True
2568 flags.append('generaldelta')
2568 flags.append('generaldelta')
2569 if not flags:
2569 if not flags:
2570 flags = ['(none)']
2570 flags = ['(none)']
2571
2571
2572 nummerges = 0
2572 nummerges = 0
2573 numfull = 0
2573 numfull = 0
2574 numprev = 0
2574 numprev = 0
2575 nump1 = 0
2575 nump1 = 0
2576 nump2 = 0
2576 nump2 = 0
2577 numother = 0
2577 numother = 0
2578 nump1prev = 0
2578 nump1prev = 0
2579 nump2prev = 0
2579 nump2prev = 0
2580 chainlengths = []
2580 chainlengths = []
2581
2581
2582 datasize = [None, 0, 0]
2582 datasize = [None, 0, 0]
2583 fullsize = [None, 0, 0]
2583 fullsize = [None, 0, 0]
2584 deltasize = [None, 0, 0]
2584 deltasize = [None, 0, 0]
2585 chunktypecounts = {}
2585 chunktypecounts = {}
2586 chunktypesizes = {}
2586 chunktypesizes = {}
2587
2587
2588 def addsize(size, l):
2588 def addsize(size, l):
2589 if l[0] is None or size < l[0]:
2589 if l[0] is None or size < l[0]:
2590 l[0] = size
2590 l[0] = size
2591 if size > l[1]:
2591 if size > l[1]:
2592 l[1] = size
2592 l[1] = size
2593 l[2] += size
2593 l[2] += size
2594
2594
2595 numrevs = len(r)
2595 numrevs = len(r)
2596 for rev in xrange(numrevs):
2596 for rev in xrange(numrevs):
2597 p1, p2 = r.parentrevs(rev)
2597 p1, p2 = r.parentrevs(rev)
2598 delta = r.deltaparent(rev)
2598 delta = r.deltaparent(rev)
2599 if format > 0:
2599 if format > 0:
2600 addsize(r.rawsize(rev), datasize)
2600 addsize(r.rawsize(rev), datasize)
2601 if p2 != nullrev:
2601 if p2 != nullrev:
2602 nummerges += 1
2602 nummerges += 1
2603 size = r.length(rev)
2603 size = r.length(rev)
2604 if delta == nullrev:
2604 if delta == nullrev:
2605 chainlengths.append(0)
2605 chainlengths.append(0)
2606 numfull += 1
2606 numfull += 1
2607 addsize(size, fullsize)
2607 addsize(size, fullsize)
2608 else:
2608 else:
2609 chainlengths.append(chainlengths[delta] + 1)
2609 chainlengths.append(chainlengths[delta] + 1)
2610 addsize(size, deltasize)
2610 addsize(size, deltasize)
2611 if delta == rev - 1:
2611 if delta == rev - 1:
2612 numprev += 1
2612 numprev += 1
2613 if delta == p1:
2613 if delta == p1:
2614 nump1prev += 1
2614 nump1prev += 1
2615 elif delta == p2:
2615 elif delta == p2:
2616 nump2prev += 1
2616 nump2prev += 1
2617 elif delta == p1:
2617 elif delta == p1:
2618 nump1 += 1
2618 nump1 += 1
2619 elif delta == p2:
2619 elif delta == p2:
2620 nump2 += 1
2620 nump2 += 1
2621 elif delta != nullrev:
2621 elif delta != nullrev:
2622 numother += 1
2622 numother += 1
2623
2623
2624 # Obtain data on the raw chunks in the revlog.
2624 # Obtain data on the raw chunks in the revlog.
2625 chunk = r._chunkraw(rev, rev)[1]
2625 chunk = r._chunkraw(rev, rev)[1]
2626 if chunk:
2626 if chunk:
2627 chunktype = chunk[0]
2627 chunktype = chunk[0]
2628 else:
2628 else:
2629 chunktype = 'empty'
2629 chunktype = 'empty'
2630
2630
2631 if chunktype not in chunktypecounts:
2631 if chunktype not in chunktypecounts:
2632 chunktypecounts[chunktype] = 0
2632 chunktypecounts[chunktype] = 0
2633 chunktypesizes[chunktype] = 0
2633 chunktypesizes[chunktype] = 0
2634
2634
2635 chunktypecounts[chunktype] += 1
2635 chunktypecounts[chunktype] += 1
2636 chunktypesizes[chunktype] += size
2636 chunktypesizes[chunktype] += size
2637
2637
2638 # Adjust size min value for empty cases
2638 # Adjust size min value for empty cases
2639 for size in (datasize, fullsize, deltasize):
2639 for size in (datasize, fullsize, deltasize):
2640 if size[0] is None:
2640 if size[0] is None:
2641 size[0] = 0
2641 size[0] = 0
2642
2642
2643 numdeltas = numrevs - numfull
2643 numdeltas = numrevs - numfull
2644 numoprev = numprev - nump1prev - nump2prev
2644 numoprev = numprev - nump1prev - nump2prev
2645 totalrawsize = datasize[2]
2645 totalrawsize = datasize[2]
2646 datasize[2] /= numrevs
2646 datasize[2] /= numrevs
2647 fulltotal = fullsize[2]
2647 fulltotal = fullsize[2]
2648 fullsize[2] /= numfull
2648 fullsize[2] /= numfull
2649 deltatotal = deltasize[2]
2649 deltatotal = deltasize[2]
2650 if numrevs - numfull > 0:
2650 if numrevs - numfull > 0:
2651 deltasize[2] /= numrevs - numfull
2651 deltasize[2] /= numrevs - numfull
2652 totalsize = fulltotal + deltatotal
2652 totalsize = fulltotal + deltatotal
2653 avgchainlen = sum(chainlengths) / numrevs
2653 avgchainlen = sum(chainlengths) / numrevs
2654 maxchainlen = max(chainlengths)
2654 maxchainlen = max(chainlengths)
2655 compratio = 1
2655 compratio = 1
2656 if totalsize:
2656 if totalsize:
2657 compratio = totalrawsize / totalsize
2657 compratio = totalrawsize / totalsize
2658
2658
2659 basedfmtstr = '%%%dd\n'
2659 basedfmtstr = '%%%dd\n'
2660 basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
2660 basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
2661
2661
2662 def dfmtstr(max):
2662 def dfmtstr(max):
2663 return basedfmtstr % len(str(max))
2663 return basedfmtstr % len(str(max))
2664 def pcfmtstr(max, padding=0):
2664 def pcfmtstr(max, padding=0):
2665 return basepcfmtstr % (len(str(max)), ' ' * padding)
2665 return basepcfmtstr % (len(str(max)), ' ' * padding)
2666
2666
2667 def pcfmt(value, total):
2667 def pcfmt(value, total):
2668 if total:
2668 if total:
2669 return (value, 100 * float(value) / total)
2669 return (value, 100 * float(value) / total)
2670 else:
2670 else:
2671 return value, 100.0
2671 return value, 100.0
2672
2672
2673 ui.write(('format : %d\n') % format)
2673 ui.write(('format : %d\n') % format)
2674 ui.write(('flags : %s\n') % ', '.join(flags))
2674 ui.write(('flags : %s\n') % ', '.join(flags))
2675
2675
2676 ui.write('\n')
2676 ui.write('\n')
2677 fmt = pcfmtstr(totalsize)
2677 fmt = pcfmtstr(totalsize)
2678 fmt2 = dfmtstr(totalsize)
2678 fmt2 = dfmtstr(totalsize)
2679 ui.write(('revisions : ') + fmt2 % numrevs)
2679 ui.write(('revisions : ') + fmt2 % numrevs)
2680 ui.write((' merges : ') + fmt % pcfmt(nummerges, numrevs))
2680 ui.write((' merges : ') + fmt % pcfmt(nummerges, numrevs))
2681 ui.write((' normal : ') + fmt % pcfmt(numrevs - nummerges, numrevs))
2681 ui.write((' normal : ') + fmt % pcfmt(numrevs - nummerges, numrevs))
2682 ui.write(('revisions : ') + fmt2 % numrevs)
2682 ui.write(('revisions : ') + fmt2 % numrevs)
2683 ui.write((' full : ') + fmt % pcfmt(numfull, numrevs))
2683 ui.write((' full : ') + fmt % pcfmt(numfull, numrevs))
2684 ui.write((' deltas : ') + fmt % pcfmt(numdeltas, numrevs))
2684 ui.write((' deltas : ') + fmt % pcfmt(numdeltas, numrevs))
2685 ui.write(('revision size : ') + fmt2 % totalsize)
2685 ui.write(('revision size : ') + fmt2 % totalsize)
2686 ui.write((' full : ') + fmt % pcfmt(fulltotal, totalsize))
2686 ui.write((' full : ') + fmt % pcfmt(fulltotal, totalsize))
2687 ui.write((' deltas : ') + fmt % pcfmt(deltatotal, totalsize))
2687 ui.write((' deltas : ') + fmt % pcfmt(deltatotal, totalsize))
2688
2688
2689 def fmtchunktype(chunktype):
2689 def fmtchunktype(chunktype):
2690 if chunktype == 'empty':
2690 if chunktype == 'empty':
2691 return ' %s : ' % chunktype
2691 return ' %s : ' % chunktype
2692 elif chunktype in string.ascii_letters:
2692 elif chunktype in string.ascii_letters:
2693 return ' 0x%s (%s) : ' % (hex(chunktype), chunktype)
2693 return ' 0x%s (%s) : ' % (hex(chunktype), chunktype)
2694 else:
2694 else:
2695 return ' 0x%s : ' % hex(chunktype)
2695 return ' 0x%s : ' % hex(chunktype)
2696
2696
2697 ui.write('\n')
2697 ui.write('\n')
2698 ui.write(('chunks : ') + fmt2 % numrevs)
2698 ui.write(('chunks : ') + fmt2 % numrevs)
2699 for chunktype in sorted(chunktypecounts):
2699 for chunktype in sorted(chunktypecounts):
2700 ui.write(fmtchunktype(chunktype))
2700 ui.write(fmtchunktype(chunktype))
2701 ui.write(fmt % pcfmt(chunktypecounts[chunktype], numrevs))
2701 ui.write(fmt % pcfmt(chunktypecounts[chunktype], numrevs))
2702 ui.write(('chunks size : ') + fmt2 % totalsize)
2702 ui.write(('chunks size : ') + fmt2 % totalsize)
2703 for chunktype in sorted(chunktypecounts):
2703 for chunktype in sorted(chunktypecounts):
2704 ui.write(fmtchunktype(chunktype))
2704 ui.write(fmtchunktype(chunktype))
2705 ui.write(fmt % pcfmt(chunktypesizes[chunktype], totalsize))
2705 ui.write(fmt % pcfmt(chunktypesizes[chunktype], totalsize))
2706
2706
2707 ui.write('\n')
2707 ui.write('\n')
2708 fmt = dfmtstr(max(avgchainlen, compratio))
2708 fmt = dfmtstr(max(avgchainlen, compratio))
2709 ui.write(('avg chain length : ') + fmt % avgchainlen)
2709 ui.write(('avg chain length : ') + fmt % avgchainlen)
2710 ui.write(('max chain length : ') + fmt % maxchainlen)
2710 ui.write(('max chain length : ') + fmt % maxchainlen)
2711 ui.write(('compression ratio : ') + fmt % compratio)
2711 ui.write(('compression ratio : ') + fmt % compratio)
2712
2712
2713 if format > 0:
2713 if format > 0:
2714 ui.write('\n')
2714 ui.write('\n')
2715 ui.write(('uncompressed data size (min/max/avg) : %d / %d / %d\n')
2715 ui.write(('uncompressed data size (min/max/avg) : %d / %d / %d\n')
2716 % tuple(datasize))
2716 % tuple(datasize))
2717 ui.write(('full revision size (min/max/avg) : %d / %d / %d\n')
2717 ui.write(('full revision size (min/max/avg) : %d / %d / %d\n')
2718 % tuple(fullsize))
2718 % tuple(fullsize))
2719 ui.write(('delta size (min/max/avg) : %d / %d / %d\n')
2719 ui.write(('delta size (min/max/avg) : %d / %d / %d\n')
2720 % tuple(deltasize))
2720 % tuple(deltasize))
2721
2721
2722 if numdeltas > 0:
2722 if numdeltas > 0:
2723 ui.write('\n')
2723 ui.write('\n')
2724 fmt = pcfmtstr(numdeltas)
2724 fmt = pcfmtstr(numdeltas)
2725 fmt2 = pcfmtstr(numdeltas, 4)
2725 fmt2 = pcfmtstr(numdeltas, 4)
2726 ui.write(('deltas against prev : ') + fmt % pcfmt(numprev, numdeltas))
2726 ui.write(('deltas against prev : ') + fmt % pcfmt(numprev, numdeltas))
2727 if numprev > 0:
2727 if numprev > 0:
2728 ui.write((' where prev = p1 : ') + fmt2 % pcfmt(nump1prev,
2728 ui.write((' where prev = p1 : ') + fmt2 % pcfmt(nump1prev,
2729 numprev))
2729 numprev))
2730 ui.write((' where prev = p2 : ') + fmt2 % pcfmt(nump2prev,
2730 ui.write((' where prev = p2 : ') + fmt2 % pcfmt(nump2prev,
2731 numprev))
2731 numprev))
2732 ui.write((' other : ') + fmt2 % pcfmt(numoprev,
2732 ui.write((' other : ') + fmt2 % pcfmt(numoprev,
2733 numprev))
2733 numprev))
2734 if gdelta:
2734 if gdelta:
2735 ui.write(('deltas against p1 : ')
2735 ui.write(('deltas against p1 : ')
2736 + fmt % pcfmt(nump1, numdeltas))
2736 + fmt % pcfmt(nump1, numdeltas))
2737 ui.write(('deltas against p2 : ')
2737 ui.write(('deltas against p2 : ')
2738 + fmt % pcfmt(nump2, numdeltas))
2738 + fmt % pcfmt(nump2, numdeltas))
2739 ui.write(('deltas against other : ') + fmt % pcfmt(numother,
2739 ui.write(('deltas against other : ') + fmt % pcfmt(numother,
2740 numdeltas))
2740 numdeltas))
2741
2741
2742 @command('debugrevspec',
2742 @command('debugrevspec',
2743 [('', 'optimize', None,
2743 [('', 'optimize', None,
2744 _('print parsed tree after optimizing (DEPRECATED)')),
2744 _('print parsed tree after optimizing (DEPRECATED)')),
2745 ('p', 'show-stage', [],
2745 ('p', 'show-stage', [],
2746 _('print parsed tree at the given stage'), _('NAME')),
2746 _('print parsed tree at the given stage'), _('NAME')),
2747 ('', 'no-optimized', False, _('evaluate tree without optimization')),
2747 ('', 'no-optimized', False, _('evaluate tree without optimization')),
2748 ('', 'verify-optimized', False, _('verify optimized result')),
2748 ('', 'verify-optimized', False, _('verify optimized result')),
2749 ],
2749 ],
2750 ('REVSPEC'))
2750 ('REVSPEC'))
2751 def debugrevspec(ui, repo, expr, **opts):
2751 def debugrevspec(ui, repo, expr, **opts):
2752 """parse and apply a revision specification
2752 """parse and apply a revision specification
2753
2753
2754 Use -p/--show-stage option to print the parsed tree at the given stages.
2754 Use -p/--show-stage option to print the parsed tree at the given stages.
2755 Use -p all to print tree at every stage.
2755 Use -p all to print tree at every stage.
2756
2756
2757 Use --verify-optimized to compare the optimized result with the unoptimized
2757 Use --verify-optimized to compare the optimized result with the unoptimized
2758 one. Returns 1 if the optimized result differs.
2758 one. Returns 1 if the optimized result differs.
2759 """
2759 """
2760 stages = [
2760 stages = [
2761 ('parsed', lambda tree: tree),
2761 ('parsed', lambda tree: tree),
2762 ('expanded', lambda tree: revset.expandaliases(ui, tree)),
2762 ('expanded', lambda tree: revset.expandaliases(ui, tree)),
2763 ('concatenated', revset.foldconcat),
2763 ('concatenated', revset.foldconcat),
2764 ('analyzed', revset.analyze),
2764 ('analyzed', revset.analyze),
2765 ('optimized', revset.optimize),
2765 ('optimized', revset.optimize),
2766 ]
2766 ]
2767 if opts['no_optimized']:
2767 if opts['no_optimized']:
2768 stages = stages[:-1]
2768 stages = stages[:-1]
2769 if opts['verify_optimized'] and opts['no_optimized']:
2769 if opts['verify_optimized'] and opts['no_optimized']:
2770 raise error.Abort(_('cannot use --verify-optimized with '
2770 raise error.Abort(_('cannot use --verify-optimized with '
2771 '--no-optimized'))
2771 '--no-optimized'))
2772 stagenames = set(n for n, f in stages)
2772 stagenames = set(n for n, f in stages)
2773
2773
2774 showalways = set()
2774 showalways = set()
2775 showchanged = set()
2775 showchanged = set()
2776 if ui.verbose and not opts['show_stage']:
2776 if ui.verbose and not opts['show_stage']:
2777 # show parsed tree by --verbose (deprecated)
2777 # show parsed tree by --verbose (deprecated)
2778 showalways.add('parsed')
2778 showalways.add('parsed')
2779 showchanged.update(['expanded', 'concatenated'])
2779 showchanged.update(['expanded', 'concatenated'])
2780 if opts['optimize']:
2780 if opts['optimize']:
2781 showalways.add('optimized')
2781 showalways.add('optimized')
2782 if opts['show_stage'] and opts['optimize']:
2782 if opts['show_stage'] and opts['optimize']:
2783 raise error.Abort(_('cannot use --optimize with --show-stage'))
2783 raise error.Abort(_('cannot use --optimize with --show-stage'))
2784 if opts['show_stage'] == ['all']:
2784 if opts['show_stage'] == ['all']:
2785 showalways.update(stagenames)
2785 showalways.update(stagenames)
2786 else:
2786 else:
2787 for n in opts['show_stage']:
2787 for n in opts['show_stage']:
2788 if n not in stagenames:
2788 if n not in stagenames:
2789 raise error.Abort(_('invalid stage name: %s') % n)
2789 raise error.Abort(_('invalid stage name: %s') % n)
2790 showalways.update(opts['show_stage'])
2790 showalways.update(opts['show_stage'])
2791
2791
2792 treebystage = {}
2792 treebystage = {}
2793 printedtree = None
2793 printedtree = None
2794 tree = revset.parse(expr, lookup=repo.__contains__)
2794 tree = revset.parse(expr, lookup=repo.__contains__)
2795 for n, f in stages:
2795 for n, f in stages:
2796 treebystage[n] = tree = f(tree)
2796 treebystage[n] = tree = f(tree)
2797 if n in showalways or (n in showchanged and tree != printedtree):
2797 if n in showalways or (n in showchanged and tree != printedtree):
2798 if opts['show_stage'] or n != 'parsed':
2798 if opts['show_stage'] or n != 'parsed':
2799 ui.write(("* %s:\n") % n)
2799 ui.write(("* %s:\n") % n)
2800 ui.write(revset.prettyformat(tree), "\n")
2800 ui.write(revset.prettyformat(tree), "\n")
2801 printedtree = tree
2801 printedtree = tree
2802
2802
2803 if opts['verify_optimized']:
2803 if opts['verify_optimized']:
2804 arevs = revset.makematcher(treebystage['analyzed'])(repo)
2804 arevs = revset.makematcher(treebystage['analyzed'])(repo)
2805 brevs = revset.makematcher(treebystage['optimized'])(repo)
2805 brevs = revset.makematcher(treebystage['optimized'])(repo)
2806 if ui.verbose:
2806 if ui.verbose:
2807 ui.note(("* analyzed set:\n"), revset.prettyformatset(arevs), "\n")
2807 ui.note(("* analyzed set:\n"), revset.prettyformatset(arevs), "\n")
2808 ui.note(("* optimized set:\n"), revset.prettyformatset(brevs), "\n")
2808 ui.note(("* optimized set:\n"), revset.prettyformatset(brevs), "\n")
2809 arevs = list(arevs)
2809 arevs = list(arevs)
2810 brevs = list(brevs)
2810 brevs = list(brevs)
2811 if arevs == brevs:
2811 if arevs == brevs:
2812 return 0
2812 return 0
2813 ui.write(('--- analyzed\n'), label='diff.file_a')
2813 ui.write(('--- analyzed\n'), label='diff.file_a')
2814 ui.write(('+++ optimized\n'), label='diff.file_b')
2814 ui.write(('+++ optimized\n'), label='diff.file_b')
2815 sm = difflib.SequenceMatcher(None, arevs, brevs)
2815 sm = difflib.SequenceMatcher(None, arevs, brevs)
2816 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
2816 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
2817 if tag in ('delete', 'replace'):
2817 if tag in ('delete', 'replace'):
2818 for c in arevs[alo:ahi]:
2818 for c in arevs[alo:ahi]:
2819 ui.write('-%s\n' % c, label='diff.deleted')
2819 ui.write('-%s\n' % c, label='diff.deleted')
2820 if tag in ('insert', 'replace'):
2820 if tag in ('insert', 'replace'):
2821 for c in brevs[blo:bhi]:
2821 for c in brevs[blo:bhi]:
2822 ui.write('+%s\n' % c, label='diff.inserted')
2822 ui.write('+%s\n' % c, label='diff.inserted')
2823 if tag == 'equal':
2823 if tag == 'equal':
2824 for c in arevs[alo:ahi]:
2824 for c in arevs[alo:ahi]:
2825 ui.write(' %s\n' % c)
2825 ui.write(' %s\n' % c)
2826 return 1
2826 return 1
2827
2827
2828 func = revset.makematcher(tree)
2828 func = revset.makematcher(tree)
2829 revs = func(repo)
2829 revs = func(repo)
2830 if ui.verbose:
2830 if ui.verbose:
2831 ui.note(("* set:\n"), revset.prettyformatset(revs), "\n")
2831 ui.note(("* set:\n"), revset.prettyformatset(revs), "\n")
2832 for c in revs:
2832 for c in revs:
2833 ui.write("%s\n" % c)
2833 ui.write("%s\n" % c)
2834
2834
2835 @command('debugsetparents', [], _('REV1 [REV2]'))
2835 @command('debugsetparents', [], _('REV1 [REV2]'))
2836 def debugsetparents(ui, repo, rev1, rev2=None):
2836 def debugsetparents(ui, repo, rev1, rev2=None):
2837 """manually set the parents of the current working directory
2837 """manually set the parents of the current working directory
2838
2838
2839 This is useful for writing repository conversion tools, but should
2839 This is useful for writing repository conversion tools, but should
2840 be used with care. For example, neither the working directory nor the
2840 be used with care. For example, neither the working directory nor the
2841 dirstate is updated, so file status may be incorrect after running this
2841 dirstate is updated, so file status may be incorrect after running this
2842 command.
2842 command.
2843
2843
2844 Returns 0 on success.
2844 Returns 0 on success.
2845 """
2845 """
2846
2846
2847 r1 = scmutil.revsingle(repo, rev1).node()
2847 r1 = scmutil.revsingle(repo, rev1).node()
2848 r2 = scmutil.revsingle(repo, rev2, 'null').node()
2848 r2 = scmutil.revsingle(repo, rev2, 'null').node()
2849
2849
2850 with repo.wlock():
2850 with repo.wlock():
2851 repo.setparents(r1, r2)
2851 repo.setparents(r1, r2)
2852
2852
2853 @command('debugdirstate|debugstate',
2853 @command('debugdirstate|debugstate',
2854 [('', 'nodates', None, _('do not display the saved mtime')),
2854 [('', 'nodates', None, _('do not display the saved mtime')),
2855 ('', 'datesort', None, _('sort by saved mtime'))],
2855 ('', 'datesort', None, _('sort by saved mtime'))],
2856 _('[OPTION]...'))
2856 _('[OPTION]...'))
2857 def debugstate(ui, repo, **opts):
2857 def debugstate(ui, repo, **opts):
2858 """show the contents of the current dirstate"""
2858 """show the contents of the current dirstate"""
2859
2859
2860 nodates = opts.get('nodates')
2860 nodates = opts.get('nodates')
2861 datesort = opts.get('datesort')
2861 datesort = opts.get('datesort')
2862
2862
2863 timestr = ""
2863 timestr = ""
2864 if datesort:
2864 if datesort:
2865 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
2865 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
2866 else:
2866 else:
2867 keyfunc = None # sort by filename
2867 keyfunc = None # sort by filename
2868 for file_, ent in sorted(repo.dirstate._map.iteritems(), key=keyfunc):
2868 for file_, ent in sorted(repo.dirstate._map.iteritems(), key=keyfunc):
2869 if ent[3] == -1:
2869 if ent[3] == -1:
2870 timestr = 'unset '
2870 timestr = 'unset '
2871 elif nodates:
2871 elif nodates:
2872 timestr = 'set '
2872 timestr = 'set '
2873 else:
2873 else:
2874 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
2874 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
2875 time.localtime(ent[3]))
2875 time.localtime(ent[3]))
2876 if ent[1] & 0o20000:
2876 if ent[1] & 0o20000:
2877 mode = 'lnk'
2877 mode = 'lnk'
2878 else:
2878 else:
2879 mode = '%3o' % (ent[1] & 0o777 & ~util.umask)
2879 mode = '%3o' % (ent[1] & 0o777 & ~util.umask)
2880 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
2880 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
2881 for f in repo.dirstate.copies():
2881 for f in repo.dirstate.copies():
2882 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
2882 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
2883
2883
2884 @command('debugsub',
2884 @command('debugsub',
2885 [('r', 'rev', '',
2885 [('r', 'rev', '',
2886 _('revision to check'), _('REV'))],
2886 _('revision to check'), _('REV'))],
2887 _('[-r REV] [REV]'))
2887 _('[-r REV] [REV]'))
2888 def debugsub(ui, repo, rev=None):
2888 def debugsub(ui, repo, rev=None):
2889 ctx = scmutil.revsingle(repo, rev, None)
2889 ctx = scmutil.revsingle(repo, rev, None)
2890 for k, v in sorted(ctx.substate.items()):
2890 for k, v in sorted(ctx.substate.items()):
2891 ui.write(('path %s\n') % k)
2891 ui.write(('path %s\n') % k)
2892 ui.write((' source %s\n') % v[0])
2892 ui.write((' source %s\n') % v[0])
2893 ui.write((' revision %s\n') % v[1])
2893 ui.write((' revision %s\n') % v[1])
2894
2894
2895 @command('debugsuccessorssets',
2895 @command('debugsuccessorssets',
2896 [],
2896 [],
2897 _('[REV]'))
2897 _('[REV]'))
2898 def debugsuccessorssets(ui, repo, *revs):
2898 def debugsuccessorssets(ui, repo, *revs):
2899 """show set of successors for revision
2899 """show set of successors for revision
2900
2900
2901 A successors set of changeset A is a consistent group of revisions that
2901 A successors set of changeset A is a consistent group of revisions that
2902 succeed A. It contains non-obsolete changesets only.
2902 succeed A. It contains non-obsolete changesets only.
2903
2903
2904 In most cases a changeset A has a single successors set containing a single
2904 In most cases a changeset A has a single successors set containing a single
2905 successor (changeset A replaced by A').
2905 successor (changeset A replaced by A').
2906
2906
2907 A changeset that is made obsolete with no successors are called "pruned".
2907 A changeset that is made obsolete with no successors are called "pruned".
2908 Such changesets have no successors sets at all.
2908 Such changesets have no successors sets at all.
2909
2909
2910 A changeset that has been "split" will have a successors set containing
2910 A changeset that has been "split" will have a successors set containing
2911 more than one successor.
2911 more than one successor.
2912
2912
2913 A changeset that has been rewritten in multiple different ways is called
2913 A changeset that has been rewritten in multiple different ways is called
2914 "divergent". Such changesets have multiple successor sets (each of which
2914 "divergent". Such changesets have multiple successor sets (each of which
2915 may also be split, i.e. have multiple successors).
2915 may also be split, i.e. have multiple successors).
2916
2916
2917 Results are displayed as follows::
2917 Results are displayed as follows::
2918
2918
2919 <rev1>
2919 <rev1>
2920 <successors-1A>
2920 <successors-1A>
2921 <rev2>
2921 <rev2>
2922 <successors-2A>
2922 <successors-2A>
2923 <successors-2B1> <successors-2B2> <successors-2B3>
2923 <successors-2B1> <successors-2B2> <successors-2B3>
2924
2924
2925 Here rev2 has two possible (i.e. divergent) successors sets. The first
2925 Here rev2 has two possible (i.e. divergent) successors sets. The first
2926 holds one element, whereas the second holds three (i.e. the changeset has
2926 holds one element, whereas the second holds three (i.e. the changeset has
2927 been split).
2927 been split).
2928 """
2928 """
2929 # passed to successorssets caching computation from one call to another
2929 # passed to successorssets caching computation from one call to another
2930 cache = {}
2930 cache = {}
2931 ctx2str = str
2931 ctx2str = str
2932 node2str = short
2932 node2str = short
2933 if ui.debug():
2933 if ui.debug():
2934 def ctx2str(ctx):
2934 def ctx2str(ctx):
2935 return ctx.hex()
2935 return ctx.hex()
2936 node2str = hex
2936 node2str = hex
2937 for rev in scmutil.revrange(repo, revs):
2937 for rev in scmutil.revrange(repo, revs):
2938 ctx = repo[rev]
2938 ctx = repo[rev]
2939 ui.write('%s\n'% ctx2str(ctx))
2939 ui.write('%s\n'% ctx2str(ctx))
2940 for succsset in obsolete.successorssets(repo, ctx.node(), cache):
2940 for succsset in obsolete.successorssets(repo, ctx.node(), cache):
2941 if succsset:
2941 if succsset:
2942 ui.write(' ')
2942 ui.write(' ')
2943 ui.write(node2str(succsset[0]))
2943 ui.write(node2str(succsset[0]))
2944 for node in succsset[1:]:
2944 for node in succsset[1:]:
2945 ui.write(' ')
2945 ui.write(' ')
2946 ui.write(node2str(node))
2946 ui.write(node2str(node))
2947 ui.write('\n')
2947 ui.write('\n')
2948
2948
2949 @command('debugtemplate',
2949 @command('debugtemplate',
2950 [('r', 'rev', [], _('apply template on changesets'), _('REV')),
2950 [('r', 'rev', [], _('apply template on changesets'), _('REV')),
2951 ('D', 'define', [], _('define template keyword'), _('KEY=VALUE'))],
2951 ('D', 'define', [], _('define template keyword'), _('KEY=VALUE'))],
2952 _('[-r REV]... [-D KEY=VALUE]... TEMPLATE'),
2952 _('[-r REV]... [-D KEY=VALUE]... TEMPLATE'),
2953 optionalrepo=True)
2953 optionalrepo=True)
2954 def debugtemplate(ui, repo, tmpl, **opts):
2954 def debugtemplate(ui, repo, tmpl, **opts):
2955 """parse and apply a template
2955 """parse and apply a template
2956
2956
2957 If -r/--rev is given, the template is processed as a log template and
2957 If -r/--rev is given, the template is processed as a log template and
2958 applied to the given changesets. Otherwise, it is processed as a generic
2958 applied to the given changesets. Otherwise, it is processed as a generic
2959 template.
2959 template.
2960
2960
2961 Use --verbose to print the parsed tree.
2961 Use --verbose to print the parsed tree.
2962 """
2962 """
2963 revs = None
2963 revs = None
2964 if opts['rev']:
2964 if opts['rev']:
2965 if repo is None:
2965 if repo is None:
2966 raise error.RepoError(_('there is no Mercurial repository here '
2966 raise error.RepoError(_('there is no Mercurial repository here '
2967 '(.hg not found)'))
2967 '(.hg not found)'))
2968 revs = scmutil.revrange(repo, opts['rev'])
2968 revs = scmutil.revrange(repo, opts['rev'])
2969
2969
2970 props = {}
2970 props = {}
2971 for d in opts['define']:
2971 for d in opts['define']:
2972 try:
2972 try:
2973 k, v = (e.strip() for e in d.split('=', 1))
2973 k, v = (e.strip() for e in d.split('=', 1))
2974 if not k:
2974 if not k:
2975 raise ValueError
2975 raise ValueError
2976 props[k] = v
2976 props[k] = v
2977 except ValueError:
2977 except ValueError:
2978 raise error.Abort(_('malformed keyword definition: %s') % d)
2978 raise error.Abort(_('malformed keyword definition: %s') % d)
2979
2979
2980 if ui.verbose:
2980 if ui.verbose:
2981 aliases = ui.configitems('templatealias')
2981 aliases = ui.configitems('templatealias')
2982 tree = templater.parse(tmpl)
2982 tree = templater.parse(tmpl)
2983 ui.note(templater.prettyformat(tree), '\n')
2983 ui.note(templater.prettyformat(tree), '\n')
2984 newtree = templater.expandaliases(tree, aliases)
2984 newtree = templater.expandaliases(tree, aliases)
2985 if newtree != tree:
2985 if newtree != tree:
2986 ui.note(("* expanded:\n"), templater.prettyformat(newtree), '\n')
2986 ui.note(("* expanded:\n"), templater.prettyformat(newtree), '\n')
2987
2987
2988 mapfile = None
2988 mapfile = None
2989 if revs is None:
2989 if revs is None:
2990 k = 'debugtemplate'
2990 k = 'debugtemplate'
2991 t = formatter.maketemplater(ui, k, tmpl)
2991 t = formatter.maketemplater(ui, k, tmpl)
2992 ui.write(templater.stringify(t(k, **props)))
2992 ui.write(templater.stringify(t(k, **props)))
2993 else:
2993 else:
2994 displayer = cmdutil.changeset_templater(ui, repo, None, opts, tmpl,
2994 displayer = cmdutil.changeset_templater(ui, repo, None, opts, tmpl,
2995 mapfile, buffered=False)
2995 mapfile, buffered=False)
2996 for r in revs:
2996 for r in revs:
2997 displayer.show(repo[r], **props)
2997 displayer.show(repo[r], **props)
2998 displayer.close()
2998 displayer.close()
2999
2999
3000 @command('debugwalk', walkopts, _('[OPTION]... [FILE]...'), inferrepo=True)
3000 @command('debugwalk', walkopts, _('[OPTION]... [FILE]...'), inferrepo=True)
3001 def debugwalk(ui, repo, *pats, **opts):
3001 def debugwalk(ui, repo, *pats, **opts):
3002 """show how files match on given patterns"""
3002 """show how files match on given patterns"""
3003 m = scmutil.match(repo[None], pats, opts)
3003 m = scmutil.match(repo[None], pats, opts)
3004 items = list(repo.walk(m))
3004 items = list(repo.walk(m))
3005 if not items:
3005 if not items:
3006 return
3006 return
3007 f = lambda fn: fn
3007 f = lambda fn: fn
3008 if ui.configbool('ui', 'slash') and pycompat.ossep != '/':
3008 if ui.configbool('ui', 'slash') and pycompat.ossep != '/':
3009 f = lambda fn: util.normpath(fn)
3009 f = lambda fn: util.normpath(fn)
3010 fmt = 'f %%-%ds %%-%ds %%s' % (
3010 fmt = 'f %%-%ds %%-%ds %%s' % (
3011 max([len(abs) for abs in items]),
3011 max([len(abs) for abs in items]),
3012 max([len(m.rel(abs)) for abs in items]))
3012 max([len(m.rel(abs)) for abs in items]))
3013 for abs in items:
3013 for abs in items:
3014 line = fmt % (abs, f(m.rel(abs)), m.exact(abs) and 'exact' or '')
3014 line = fmt % (abs, f(m.rel(abs)), m.exact(abs) and 'exact' or '')
3015 ui.write("%s\n" % line.rstrip())
3015 ui.write("%s\n" % line.rstrip())
3016
3016
3017 @command('debugwireargs',
3017 @command('debugwireargs',
3018 [('', 'three', '', 'three'),
3018 [('', 'three', '', 'three'),
3019 ('', 'four', '', 'four'),
3019 ('', 'four', '', 'four'),
3020 ('', 'five', '', 'five'),
3020 ('', 'five', '', 'five'),
3021 ] + remoteopts,
3021 ] + remoteopts,
3022 _('REPO [OPTIONS]... [ONE [TWO]]'),
3022 _('REPO [OPTIONS]... [ONE [TWO]]'),
3023 norepo=True)
3023 norepo=True)
3024 def debugwireargs(ui, repopath, *vals, **opts):
3024 def debugwireargs(ui, repopath, *vals, **opts):
3025 repo = hg.peer(ui, opts, repopath)
3025 repo = hg.peer(ui, opts, repopath)
3026 for opt in remoteopts:
3026 for opt in remoteopts:
3027 del opts[opt[1]]
3027 del opts[opt[1]]
3028 args = {}
3028 args = {}
3029 for k, v in opts.iteritems():
3029 for k, v in opts.iteritems():
3030 if v:
3030 if v:
3031 args[k] = v
3031 args[k] = v
3032 # run twice to check that we don't mess up the stream for the next command
3032 # run twice to check that we don't mess up the stream for the next command
3033 res1 = repo.debugwireargs(*vals, **args)
3033 res1 = repo.debugwireargs(*vals, **args)
3034 res2 = repo.debugwireargs(*vals, **args)
3034 res2 = repo.debugwireargs(*vals, **args)
3035 ui.write("%s\n" % res1)
3035 ui.write("%s\n" % res1)
3036 if res1 != res2:
3036 if res1 != res2:
3037 ui.warn("%s\n" % res2)
3037 ui.warn("%s\n" % res2)
3038
3038
3039 @command('^diff',
3039 @command('^diff',
3040 [('r', 'rev', [], _('revision'), _('REV')),
3040 [('r', 'rev', [], _('revision'), _('REV')),
3041 ('c', 'change', '', _('change made by revision'), _('REV'))
3041 ('c', 'change', '', _('change made by revision'), _('REV'))
3042 ] + diffopts + diffopts2 + walkopts + subrepoopts,
3042 ] + diffopts + diffopts2 + walkopts + subrepoopts,
3043 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'),
3043 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'),
3044 inferrepo=True)
3044 inferrepo=True)
3045 def diff(ui, repo, *pats, **opts):
3045 def diff(ui, repo, *pats, **opts):
3046 """diff repository (or selected files)
3046 """diff repository (or selected files)
3047
3047
3048 Show differences between revisions for the specified files.
3048 Show differences between revisions for the specified files.
3049
3049
3050 Differences between files are shown using the unified diff format.
3050 Differences between files are shown using the unified diff format.
3051
3051
3052 .. note::
3052 .. note::
3053
3053
3054 :hg:`diff` may generate unexpected results for merges, as it will
3054 :hg:`diff` may generate unexpected results for merges, as it will
3055 default to comparing against the working directory's first
3055 default to comparing against the working directory's first
3056 parent changeset if no revisions are specified.
3056 parent changeset if no revisions are specified.
3057
3057
3058 When two revision arguments are given, then changes are shown
3058 When two revision arguments are given, then changes are shown
3059 between those revisions. If only one revision is specified then
3059 between those revisions. If only one revision is specified then
3060 that revision is compared to the working directory, and, when no
3060 that revision is compared to the working directory, and, when no
3061 revisions are specified, the working directory files are compared
3061 revisions are specified, the working directory files are compared
3062 to its first parent.
3062 to its first parent.
3063
3063
3064 Alternatively you can specify -c/--change with a revision to see
3064 Alternatively you can specify -c/--change with a revision to see
3065 the changes in that changeset relative to its first parent.
3065 the changes in that changeset relative to its first parent.
3066
3066
3067 Without the -a/--text option, diff will avoid generating diffs of
3067 Without the -a/--text option, diff will avoid generating diffs of
3068 files it detects as binary. With -a, diff will generate a diff
3068 files it detects as binary. With -a, diff will generate a diff
3069 anyway, probably with undesirable results.
3069 anyway, probably with undesirable results.
3070
3070
3071 Use the -g/--git option to generate diffs in the git extended diff
3071 Use the -g/--git option to generate diffs in the git extended diff
3072 format. For more information, read :hg:`help diffs`.
3072 format. For more information, read :hg:`help diffs`.
3073
3073
3074 .. container:: verbose
3074 .. container:: verbose
3075
3075
3076 Examples:
3076 Examples:
3077
3077
3078 - compare a file in the current working directory to its parent::
3078 - compare a file in the current working directory to its parent::
3079
3079
3080 hg diff foo.c
3080 hg diff foo.c
3081
3081
3082 - compare two historical versions of a directory, with rename info::
3082 - compare two historical versions of a directory, with rename info::
3083
3083
3084 hg diff --git -r 1.0:1.2 lib/
3084 hg diff --git -r 1.0:1.2 lib/
3085
3085
3086 - get change stats relative to the last change on some date::
3086 - get change stats relative to the last change on some date::
3087
3087
3088 hg diff --stat -r "date('may 2')"
3088 hg diff --stat -r "date('may 2')"
3089
3089
3090 - diff all newly-added files that contain a keyword::
3090 - diff all newly-added files that contain a keyword::
3091
3091
3092 hg diff "set:added() and grep(GNU)"
3092 hg diff "set:added() and grep(GNU)"
3093
3093
3094 - compare a revision and its parents::
3094 - compare a revision and its parents::
3095
3095
3096 hg diff -c 9353 # compare against first parent
3096 hg diff -c 9353 # compare against first parent
3097 hg diff -r 9353^:9353 # same using revset syntax
3097 hg diff -r 9353^:9353 # same using revset syntax
3098 hg diff -r 9353^2:9353 # compare against the second parent
3098 hg diff -r 9353^2:9353 # compare against the second parent
3099
3099
3100 Returns 0 on success.
3100 Returns 0 on success.
3101 """
3101 """
3102
3102
3103 revs = opts.get('rev')
3103 revs = opts.get('rev')
3104 change = opts.get('change')
3104 change = opts.get('change')
3105 stat = opts.get('stat')
3105 stat = opts.get('stat')
3106 reverse = opts.get('reverse')
3106 reverse = opts.get('reverse')
3107
3107
3108 if revs and change:
3108 if revs and change:
3109 msg = _('cannot specify --rev and --change at the same time')
3109 msg = _('cannot specify --rev and --change at the same time')
3110 raise error.Abort(msg)
3110 raise error.Abort(msg)
3111 elif change:
3111 elif change:
3112 node2 = scmutil.revsingle(repo, change, None).node()
3112 node2 = scmutil.revsingle(repo, change, None).node()
3113 node1 = repo[node2].p1().node()
3113 node1 = repo[node2].p1().node()
3114 else:
3114 else:
3115 node1, node2 = scmutil.revpair(repo, revs)
3115 node1, node2 = scmutil.revpair(repo, revs)
3116
3116
3117 if reverse:
3117 if reverse:
3118 node1, node2 = node2, node1
3118 node1, node2 = node2, node1
3119
3119
3120 diffopts = patch.diffallopts(ui, opts)
3120 diffopts = patch.diffallopts(ui, opts)
3121 m = scmutil.match(repo[node2], pats, opts)
3121 m = scmutil.match(repo[node2], pats, opts)
3122 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
3122 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
3123 listsubrepos=opts.get('subrepos'),
3123 listsubrepos=opts.get('subrepos'),
3124 root=opts.get('root'))
3124 root=opts.get('root'))
3125
3125
3126 @command('^export',
3126 @command('^export',
3127 [('o', 'output', '',
3127 [('o', 'output', '',
3128 _('print output to file with formatted name'), _('FORMAT')),
3128 _('print output to file with formatted name'), _('FORMAT')),
3129 ('', 'switch-parent', None, _('diff against the second parent')),
3129 ('', 'switch-parent', None, _('diff against the second parent')),
3130 ('r', 'rev', [], _('revisions to export'), _('REV')),
3130 ('r', 'rev', [], _('revisions to export'), _('REV')),
3131 ] + diffopts,
3131 ] + diffopts,
3132 _('[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'))
3132 _('[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'))
3133 def export(ui, repo, *changesets, **opts):
3133 def export(ui, repo, *changesets, **opts):
3134 """dump the header and diffs for one or more changesets
3134 """dump the header and diffs for one or more changesets
3135
3135
3136 Print the changeset header and diffs for one or more revisions.
3136 Print the changeset header and diffs for one or more revisions.
3137 If no revision is given, the parent of the working directory is used.
3137 If no revision is given, the parent of the working directory is used.
3138
3138
3139 The information shown in the changeset header is: author, date,
3139 The information shown in the changeset header is: author, date,
3140 branch name (if non-default), changeset hash, parent(s) and commit
3140 branch name (if non-default), changeset hash, parent(s) and commit
3141 comment.
3141 comment.
3142
3142
3143 .. note::
3143 .. note::
3144
3144
3145 :hg:`export` may generate unexpected diff output for merge
3145 :hg:`export` may generate unexpected diff output for merge
3146 changesets, as it will compare the merge changeset against its
3146 changesets, as it will compare the merge changeset against its
3147 first parent only.
3147 first parent only.
3148
3148
3149 Output may be to a file, in which case the name of the file is
3149 Output may be to a file, in which case the name of the file is
3150 given using a format string. The formatting rules are as follows:
3150 given using a format string. The formatting rules are as follows:
3151
3151
3152 :``%%``: literal "%" character
3152 :``%%``: literal "%" character
3153 :``%H``: changeset hash (40 hexadecimal digits)
3153 :``%H``: changeset hash (40 hexadecimal digits)
3154 :``%N``: number of patches being generated
3154 :``%N``: number of patches being generated
3155 :``%R``: changeset revision number
3155 :``%R``: changeset revision number
3156 :``%b``: basename of the exporting repository
3156 :``%b``: basename of the exporting repository
3157 :``%h``: short-form changeset hash (12 hexadecimal digits)
3157 :``%h``: short-form changeset hash (12 hexadecimal digits)
3158 :``%m``: first line of the commit message (only alphanumeric characters)
3158 :``%m``: first line of the commit message (only alphanumeric characters)
3159 :``%n``: zero-padded sequence number, starting at 1
3159 :``%n``: zero-padded sequence number, starting at 1
3160 :``%r``: zero-padded changeset revision number
3160 :``%r``: zero-padded changeset revision number
3161
3161
3162 Without the -a/--text option, export will avoid generating diffs
3162 Without the -a/--text option, export will avoid generating diffs
3163 of files it detects as binary. With -a, export will generate a
3163 of files it detects as binary. With -a, export will generate a
3164 diff anyway, probably with undesirable results.
3164 diff anyway, probably with undesirable results.
3165
3165
3166 Use the -g/--git option to generate diffs in the git extended diff
3166 Use the -g/--git option to generate diffs in the git extended diff
3167 format. See :hg:`help diffs` for more information.
3167 format. See :hg:`help diffs` for more information.
3168
3168
3169 With the --switch-parent option, the diff will be against the
3169 With the --switch-parent option, the diff will be against the
3170 second parent. It can be useful to review a merge.
3170 second parent. It can be useful to review a merge.
3171
3171
3172 .. container:: verbose
3172 .. container:: verbose
3173
3173
3174 Examples:
3174 Examples:
3175
3175
3176 - use export and import to transplant a bugfix to the current
3176 - use export and import to transplant a bugfix to the current
3177 branch::
3177 branch::
3178
3178
3179 hg export -r 9353 | hg import -
3179 hg export -r 9353 | hg import -
3180
3180
3181 - export all the changesets between two revisions to a file with
3181 - export all the changesets between two revisions to a file with
3182 rename information::
3182 rename information::
3183
3183
3184 hg export --git -r 123:150 > changes.txt
3184 hg export --git -r 123:150 > changes.txt
3185
3185
3186 - split outgoing changes into a series of patches with
3186 - split outgoing changes into a series of patches with
3187 descriptive names::
3187 descriptive names::
3188
3188
3189 hg export -r "outgoing()" -o "%n-%m.patch"
3189 hg export -r "outgoing()" -o "%n-%m.patch"
3190
3190
3191 Returns 0 on success.
3191 Returns 0 on success.
3192 """
3192 """
3193 changesets += tuple(opts.get('rev', []))
3193 changesets += tuple(opts.get('rev', []))
3194 if not changesets:
3194 if not changesets:
3195 changesets = ['.']
3195 changesets = ['.']
3196 revs = scmutil.revrange(repo, changesets)
3196 revs = scmutil.revrange(repo, changesets)
3197 if not revs:
3197 if not revs:
3198 raise error.Abort(_("export requires at least one changeset"))
3198 raise error.Abort(_("export requires at least one changeset"))
3199 if len(revs) > 1:
3199 if len(revs) > 1:
3200 ui.note(_('exporting patches:\n'))
3200 ui.note(_('exporting patches:\n'))
3201 else:
3201 else:
3202 ui.note(_('exporting patch:\n'))
3202 ui.note(_('exporting patch:\n'))
3203 cmdutil.export(repo, revs, template=opts.get('output'),
3203 cmdutil.export(repo, revs, template=opts.get('output'),
3204 switch_parent=opts.get('switch_parent'),
3204 switch_parent=opts.get('switch_parent'),
3205 opts=patch.diffallopts(ui, opts))
3205 opts=patch.diffallopts(ui, opts))
3206
3206
3207 @command('files',
3207 @command('files',
3208 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
3208 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
3209 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
3209 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
3210 ] + walkopts + formatteropts + subrepoopts,
3210 ] + walkopts + formatteropts + subrepoopts,
3211 _('[OPTION]... [FILE]...'))
3211 _('[OPTION]... [FILE]...'))
3212 def files(ui, repo, *pats, **opts):
3212 def files(ui, repo, *pats, **opts):
3213 """list tracked files
3213 """list tracked files
3214
3214
3215 Print files under Mercurial control in the working directory or
3215 Print files under Mercurial control in the working directory or
3216 specified revision for given files (excluding removed files).
3216 specified revision for given files (excluding removed files).
3217 Files can be specified as filenames or filesets.
3217 Files can be specified as filenames or filesets.
3218
3218
3219 If no files are given to match, this command prints the names
3219 If no files are given to match, this command prints the names
3220 of all files under Mercurial control.
3220 of all files under Mercurial control.
3221
3221
3222 .. container:: verbose
3222 .. container:: verbose
3223
3223
3224 Examples:
3224 Examples:
3225
3225
3226 - list all files under the current directory::
3226 - list all files under the current directory::
3227
3227
3228 hg files .
3228 hg files .
3229
3229
3230 - shows sizes and flags for current revision::
3230 - shows sizes and flags for current revision::
3231
3231
3232 hg files -vr .
3232 hg files -vr .
3233
3233
3234 - list all files named README::
3234 - list all files named README::
3235
3235
3236 hg files -I "**/README"
3236 hg files -I "**/README"
3237
3237
3238 - list all binary files::
3238 - list all binary files::
3239
3239
3240 hg files "set:binary()"
3240 hg files "set:binary()"
3241
3241
3242 - find files containing a regular expression::
3242 - find files containing a regular expression::
3243
3243
3244 hg files "set:grep('bob')"
3244 hg files "set:grep('bob')"
3245
3245
3246 - search tracked file contents with xargs and grep::
3246 - search tracked file contents with xargs and grep::
3247
3247
3248 hg files -0 | xargs -0 grep foo
3248 hg files -0 | xargs -0 grep foo
3249
3249
3250 See :hg:`help patterns` and :hg:`help filesets` for more information
3250 See :hg:`help patterns` and :hg:`help filesets` for more information
3251 on specifying file patterns.
3251 on specifying file patterns.
3252
3252
3253 Returns 0 if a match is found, 1 otherwise.
3253 Returns 0 if a match is found, 1 otherwise.
3254
3254
3255 """
3255 """
3256 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
3256 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
3257
3257
3258 end = '\n'
3258 end = '\n'
3259 if opts.get('print0'):
3259 if opts.get('print0'):
3260 end = '\0'
3260 end = '\0'
3261 fmt = '%s' + end
3261 fmt = '%s' + end
3262
3262
3263 m = scmutil.match(ctx, pats, opts)
3263 m = scmutil.match(ctx, pats, opts)
3264 with ui.formatter('files', opts) as fm:
3264 with ui.formatter('files', opts) as fm:
3265 return cmdutil.files(ui, ctx, m, fm, fmt, opts.get('subrepos'))
3265 return cmdutil.files(ui, ctx, m, fm, fmt, opts.get('subrepos'))
3266
3266
3267 @command('^forget', walkopts, _('[OPTION]... FILE...'), inferrepo=True)
3267 @command('^forget', walkopts, _('[OPTION]... FILE...'), inferrepo=True)
3268 def forget(ui, repo, *pats, **opts):
3268 def forget(ui, repo, *pats, **opts):
3269 """forget the specified files on the next commit
3269 """forget the specified files on the next commit
3270
3270
3271 Mark the specified files so they will no longer be tracked
3271 Mark the specified files so they will no longer be tracked
3272 after the next commit.
3272 after the next commit.
3273
3273
3274 This only removes files from the current branch, not from the
3274 This only removes files from the current branch, not from the
3275 entire project history, and it does not delete them from the
3275 entire project history, and it does not delete them from the
3276 working directory.
3276 working directory.
3277
3277
3278 To delete the file from the working directory, see :hg:`remove`.
3278 To delete the file from the working directory, see :hg:`remove`.
3279
3279
3280 To undo a forget before the next commit, see :hg:`add`.
3280 To undo a forget before the next commit, see :hg:`add`.
3281
3281
3282 .. container:: verbose
3282 .. container:: verbose
3283
3283
3284 Examples:
3284 Examples:
3285
3285
3286 - forget newly-added binary files::
3286 - forget newly-added binary files::
3287
3287
3288 hg forget "set:added() and binary()"
3288 hg forget "set:added() and binary()"
3289
3289
3290 - forget files that would be excluded by .hgignore::
3290 - forget files that would be excluded by .hgignore::
3291
3291
3292 hg forget "set:hgignore()"
3292 hg forget "set:hgignore()"
3293
3293
3294 Returns 0 on success.
3294 Returns 0 on success.
3295 """
3295 """
3296
3296
3297 if not pats:
3297 if not pats:
3298 raise error.Abort(_('no files specified'))
3298 raise error.Abort(_('no files specified'))
3299
3299
3300 m = scmutil.match(repo[None], pats, opts)
3300 m = scmutil.match(repo[None], pats, opts)
3301 rejected = cmdutil.forget(ui, repo, m, prefix="", explicitonly=False)[0]
3301 rejected = cmdutil.forget(ui, repo, m, prefix="", explicitonly=False)[0]
3302 return rejected and 1 or 0
3302 return rejected and 1 or 0
3303
3303
3304 @command(
3304 @command(
3305 'graft',
3305 'graft',
3306 [('r', 'rev', [], _('revisions to graft'), _('REV')),
3306 [('r', 'rev', [], _('revisions to graft'), _('REV')),
3307 ('c', 'continue', False, _('resume interrupted graft')),
3307 ('c', 'continue', False, _('resume interrupted graft')),
3308 ('e', 'edit', False, _('invoke editor on commit messages')),
3308 ('e', 'edit', False, _('invoke editor on commit messages')),
3309 ('', 'log', None, _('append graft info to log message')),
3309 ('', 'log', None, _('append graft info to log message')),
3310 ('f', 'force', False, _('force graft')),
3310 ('f', 'force', False, _('force graft')),
3311 ('D', 'currentdate', False,
3311 ('D', 'currentdate', False,
3312 _('record the current date as commit date')),
3312 _('record the current date as commit date')),
3313 ('U', 'currentuser', False,
3313 ('U', 'currentuser', False,
3314 _('record the current user as committer'), _('DATE'))]
3314 _('record the current user as committer'), _('DATE'))]
3315 + commitopts2 + mergetoolopts + dryrunopts,
3315 + commitopts2 + mergetoolopts + dryrunopts,
3316 _('[OPTION]... [-r REV]... REV...'))
3316 _('[OPTION]... [-r REV]... REV...'))
3317 def graft(ui, repo, *revs, **opts):
3317 def graft(ui, repo, *revs, **opts):
3318 '''copy changes from other branches onto the current branch
3318 '''copy changes from other branches onto the current branch
3319
3319
3320 This command uses Mercurial's merge logic to copy individual
3320 This command uses Mercurial's merge logic to copy individual
3321 changes from other branches without merging branches in the
3321 changes from other branches without merging branches in the
3322 history graph. This is sometimes known as 'backporting' or
3322 history graph. This is sometimes known as 'backporting' or
3323 'cherry-picking'. By default, graft will copy user, date, and
3323 'cherry-picking'. By default, graft will copy user, date, and
3324 description from the source changesets.
3324 description from the source changesets.
3325
3325
3326 Changesets that are ancestors of the current revision, that have
3326 Changesets that are ancestors of the current revision, that have
3327 already been grafted, or that are merges will be skipped.
3327 already been grafted, or that are merges will be skipped.
3328
3328
3329 If --log is specified, log messages will have a comment appended
3329 If --log is specified, log messages will have a comment appended
3330 of the form::
3330 of the form::
3331
3331
3332 (grafted from CHANGESETHASH)
3332 (grafted from CHANGESETHASH)
3333
3333
3334 If --force is specified, revisions will be grafted even if they
3334 If --force is specified, revisions will be grafted even if they
3335 are already ancestors of or have been grafted to the destination.
3335 are already ancestors of or have been grafted to the destination.
3336 This is useful when the revisions have since been backed out.
3336 This is useful when the revisions have since been backed out.
3337
3337
3338 If a graft merge results in conflicts, the graft process is
3338 If a graft merge results in conflicts, the graft process is
3339 interrupted so that the current merge can be manually resolved.
3339 interrupted so that the current merge can be manually resolved.
3340 Once all conflicts are addressed, the graft process can be
3340 Once all conflicts are addressed, the graft process can be
3341 continued with the -c/--continue option.
3341 continued with the -c/--continue option.
3342
3342
3343 .. note::
3343 .. note::
3344
3344
3345 The -c/--continue option does not reapply earlier options, except
3345 The -c/--continue option does not reapply earlier options, except
3346 for --force.
3346 for --force.
3347
3347
3348 .. container:: verbose
3348 .. container:: verbose
3349
3349
3350 Examples:
3350 Examples:
3351
3351
3352 - copy a single change to the stable branch and edit its description::
3352 - copy a single change to the stable branch and edit its description::
3353
3353
3354 hg update stable
3354 hg update stable
3355 hg graft --edit 9393
3355 hg graft --edit 9393
3356
3356
3357 - graft a range of changesets with one exception, updating dates::
3357 - graft a range of changesets with one exception, updating dates::
3358
3358
3359 hg graft -D "2085::2093 and not 2091"
3359 hg graft -D "2085::2093 and not 2091"
3360
3360
3361 - continue a graft after resolving conflicts::
3361 - continue a graft after resolving conflicts::
3362
3362
3363 hg graft -c
3363 hg graft -c
3364
3364
3365 - show the source of a grafted changeset::
3365 - show the source of a grafted changeset::
3366
3366
3367 hg log --debug -r .
3367 hg log --debug -r .
3368
3368
3369 - show revisions sorted by date::
3369 - show revisions sorted by date::
3370
3370
3371 hg log -r "sort(all(), date)"
3371 hg log -r "sort(all(), date)"
3372
3372
3373 See :hg:`help revisions` for more about specifying revisions.
3373 See :hg:`help revisions` for more about specifying revisions.
3374
3374
3375 Returns 0 on successful completion.
3375 Returns 0 on successful completion.
3376 '''
3376 '''
3377 with repo.wlock():
3377 with repo.wlock():
3378 return _dograft(ui, repo, *revs, **opts)
3378 return _dograft(ui, repo, *revs, **opts)
3379
3379
3380 def _dograft(ui, repo, *revs, **opts):
3380 def _dograft(ui, repo, *revs, **opts):
3381 if revs and opts.get('rev'):
3381 if revs and opts.get('rev'):
3382 ui.warn(_('warning: inconsistent use of --rev might give unexpected '
3382 ui.warn(_('warning: inconsistent use of --rev might give unexpected '
3383 'revision ordering!\n'))
3383 'revision ordering!\n'))
3384
3384
3385 revs = list(revs)
3385 revs = list(revs)
3386 revs.extend(opts.get('rev'))
3386 revs.extend(opts.get('rev'))
3387
3387
3388 if not opts.get('user') and opts.get('currentuser'):
3388 if not opts.get('user') and opts.get('currentuser'):
3389 opts['user'] = ui.username()
3389 opts['user'] = ui.username()
3390 if not opts.get('date') and opts.get('currentdate'):
3390 if not opts.get('date') and opts.get('currentdate'):
3391 opts['date'] = "%d %d" % util.makedate()
3391 opts['date'] = "%d %d" % util.makedate()
3392
3392
3393 editor = cmdutil.getcommiteditor(editform='graft', **opts)
3393 editor = cmdutil.getcommiteditor(editform='graft', **opts)
3394
3394
3395 cont = False
3395 cont = False
3396 if opts.get('continue'):
3396 if opts.get('continue'):
3397 cont = True
3397 cont = True
3398 if revs:
3398 if revs:
3399 raise error.Abort(_("can't specify --continue and revisions"))
3399 raise error.Abort(_("can't specify --continue and revisions"))
3400 # read in unfinished revisions
3400 # read in unfinished revisions
3401 try:
3401 try:
3402 nodes = repo.vfs.read('graftstate').splitlines()
3402 nodes = repo.vfs.read('graftstate').splitlines()
3403 revs = [repo[node].rev() for node in nodes]
3403 revs = [repo[node].rev() for node in nodes]
3404 except IOError as inst:
3404 except IOError as inst:
3405 if inst.errno != errno.ENOENT:
3405 if inst.errno != errno.ENOENT:
3406 raise
3406 raise
3407 cmdutil.wrongtooltocontinue(repo, _('graft'))
3407 cmdutil.wrongtooltocontinue(repo, _('graft'))
3408 else:
3408 else:
3409 cmdutil.checkunfinished(repo)
3409 cmdutil.checkunfinished(repo)
3410 cmdutil.bailifchanged(repo)
3410 cmdutil.bailifchanged(repo)
3411 if not revs:
3411 if not revs:
3412 raise error.Abort(_('no revisions specified'))
3412 raise error.Abort(_('no revisions specified'))
3413 revs = scmutil.revrange(repo, revs)
3413 revs = scmutil.revrange(repo, revs)
3414
3414
3415 skipped = set()
3415 skipped = set()
3416 # check for merges
3416 # check for merges
3417 for rev in repo.revs('%ld and merge()', revs):
3417 for rev in repo.revs('%ld and merge()', revs):
3418 ui.warn(_('skipping ungraftable merge revision %s\n') % rev)
3418 ui.warn(_('skipping ungraftable merge revision %s\n') % rev)
3419 skipped.add(rev)
3419 skipped.add(rev)
3420 revs = [r for r in revs if r not in skipped]
3420 revs = [r for r in revs if r not in skipped]
3421 if not revs:
3421 if not revs:
3422 return -1
3422 return -1
3423
3423
3424 # Don't check in the --continue case, in effect retaining --force across
3424 # Don't check in the --continue case, in effect retaining --force across
3425 # --continues. That's because without --force, any revisions we decided to
3425 # --continues. That's because without --force, any revisions we decided to
3426 # skip would have been filtered out here, so they wouldn't have made their
3426 # skip would have been filtered out here, so they wouldn't have made their
3427 # way to the graftstate. With --force, any revisions we would have otherwise
3427 # way to the graftstate. With --force, any revisions we would have otherwise
3428 # skipped would not have been filtered out, and if they hadn't been applied
3428 # skipped would not have been filtered out, and if they hadn't been applied
3429 # already, they'd have been in the graftstate.
3429 # already, they'd have been in the graftstate.
3430 if not (cont or opts.get('force')):
3430 if not (cont or opts.get('force')):
3431 # check for ancestors of dest branch
3431 # check for ancestors of dest branch
3432 crev = repo['.'].rev()
3432 crev = repo['.'].rev()
3433 ancestors = repo.changelog.ancestors([crev], inclusive=True)
3433 ancestors = repo.changelog.ancestors([crev], inclusive=True)
3434 # XXX make this lazy in the future
3434 # XXX make this lazy in the future
3435 # don't mutate while iterating, create a copy
3435 # don't mutate while iterating, create a copy
3436 for rev in list(revs):
3436 for rev in list(revs):
3437 if rev in ancestors:
3437 if rev in ancestors:
3438 ui.warn(_('skipping ancestor revision %d:%s\n') %
3438 ui.warn(_('skipping ancestor revision %d:%s\n') %
3439 (rev, repo[rev]))
3439 (rev, repo[rev]))
3440 # XXX remove on list is slow
3440 # XXX remove on list is slow
3441 revs.remove(rev)
3441 revs.remove(rev)
3442 if not revs:
3442 if not revs:
3443 return -1
3443 return -1
3444
3444
3445 # analyze revs for earlier grafts
3445 # analyze revs for earlier grafts
3446 ids = {}
3446 ids = {}
3447 for ctx in repo.set("%ld", revs):
3447 for ctx in repo.set("%ld", revs):
3448 ids[ctx.hex()] = ctx.rev()
3448 ids[ctx.hex()] = ctx.rev()
3449 n = ctx.extra().get('source')
3449 n = ctx.extra().get('source')
3450 if n:
3450 if n:
3451 ids[n] = ctx.rev()
3451 ids[n] = ctx.rev()
3452
3452
3453 # check ancestors for earlier grafts
3453 # check ancestors for earlier grafts
3454 ui.debug('scanning for duplicate grafts\n')
3454 ui.debug('scanning for duplicate grafts\n')
3455
3455
3456 for rev in repo.changelog.findmissingrevs(revs, [crev]):
3456 for rev in repo.changelog.findmissingrevs(revs, [crev]):
3457 ctx = repo[rev]
3457 ctx = repo[rev]
3458 n = ctx.extra().get('source')
3458 n = ctx.extra().get('source')
3459 if n in ids:
3459 if n in ids:
3460 try:
3460 try:
3461 r = repo[n].rev()
3461 r = repo[n].rev()
3462 except error.RepoLookupError:
3462 except error.RepoLookupError:
3463 r = None
3463 r = None
3464 if r in revs:
3464 if r in revs:
3465 ui.warn(_('skipping revision %d:%s '
3465 ui.warn(_('skipping revision %d:%s '
3466 '(already grafted to %d:%s)\n')
3466 '(already grafted to %d:%s)\n')
3467 % (r, repo[r], rev, ctx))
3467 % (r, repo[r], rev, ctx))
3468 revs.remove(r)
3468 revs.remove(r)
3469 elif ids[n] in revs:
3469 elif ids[n] in revs:
3470 if r is None:
3470 if r is None:
3471 ui.warn(_('skipping already grafted revision %d:%s '
3471 ui.warn(_('skipping already grafted revision %d:%s '
3472 '(%d:%s also has unknown origin %s)\n')
3472 '(%d:%s also has unknown origin %s)\n')
3473 % (ids[n], repo[ids[n]], rev, ctx, n[:12]))
3473 % (ids[n], repo[ids[n]], rev, ctx, n[:12]))
3474 else:
3474 else:
3475 ui.warn(_('skipping already grafted revision %d:%s '
3475 ui.warn(_('skipping already grafted revision %d:%s '
3476 '(%d:%s also has origin %d:%s)\n')
3476 '(%d:%s also has origin %d:%s)\n')
3477 % (ids[n], repo[ids[n]], rev, ctx, r, n[:12]))
3477 % (ids[n], repo[ids[n]], rev, ctx, r, n[:12]))
3478 revs.remove(ids[n])
3478 revs.remove(ids[n])
3479 elif ctx.hex() in ids:
3479 elif ctx.hex() in ids:
3480 r = ids[ctx.hex()]
3480 r = ids[ctx.hex()]
3481 ui.warn(_('skipping already grafted revision %d:%s '
3481 ui.warn(_('skipping already grafted revision %d:%s '
3482 '(was grafted from %d:%s)\n') %
3482 '(was grafted from %d:%s)\n') %
3483 (r, repo[r], rev, ctx))
3483 (r, repo[r], rev, ctx))
3484 revs.remove(r)
3484 revs.remove(r)
3485 if not revs:
3485 if not revs:
3486 return -1
3486 return -1
3487
3487
3488 for pos, ctx in enumerate(repo.set("%ld", revs)):
3488 for pos, ctx in enumerate(repo.set("%ld", revs)):
3489 desc = '%d:%s "%s"' % (ctx.rev(), ctx,
3489 desc = '%d:%s "%s"' % (ctx.rev(), ctx,
3490 ctx.description().split('\n', 1)[0])
3490 ctx.description().split('\n', 1)[0])
3491 names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node())
3491 names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node())
3492 if names:
3492 if names:
3493 desc += ' (%s)' % ' '.join(names)
3493 desc += ' (%s)' % ' '.join(names)
3494 ui.status(_('grafting %s\n') % desc)
3494 ui.status(_('grafting %s\n') % desc)
3495 if opts.get('dry_run'):
3495 if opts.get('dry_run'):
3496 continue
3496 continue
3497
3497
3498 source = ctx.extra().get('source')
3498 source = ctx.extra().get('source')
3499 extra = {}
3499 extra = {}
3500 if source:
3500 if source:
3501 extra['source'] = source
3501 extra['source'] = source
3502 extra['intermediate-source'] = ctx.hex()
3502 extra['intermediate-source'] = ctx.hex()
3503 else:
3503 else:
3504 extra['source'] = ctx.hex()
3504 extra['source'] = ctx.hex()
3505 user = ctx.user()
3505 user = ctx.user()
3506 if opts.get('user'):
3506 if opts.get('user'):
3507 user = opts['user']
3507 user = opts['user']
3508 date = ctx.date()
3508 date = ctx.date()
3509 if opts.get('date'):
3509 if opts.get('date'):
3510 date = opts['date']
3510 date = opts['date']
3511 message = ctx.description()
3511 message = ctx.description()
3512 if opts.get('log'):
3512 if opts.get('log'):
3513 message += '\n(grafted from %s)' % ctx.hex()
3513 message += '\n(grafted from %s)' % ctx.hex()
3514
3514
3515 # we don't merge the first commit when continuing
3515 # we don't merge the first commit when continuing
3516 if not cont:
3516 if not cont:
3517 # perform the graft merge with p1(rev) as 'ancestor'
3517 # perform the graft merge with p1(rev) as 'ancestor'
3518 try:
3518 try:
3519 # ui.forcemerge is an internal variable, do not document
3519 # ui.forcemerge is an internal variable, do not document
3520 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
3520 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
3521 'graft')
3521 'graft')
3522 stats = mergemod.graft(repo, ctx, ctx.p1(),
3522 stats = mergemod.graft(repo, ctx, ctx.p1(),
3523 ['local', 'graft'])
3523 ['local', 'graft'])
3524 finally:
3524 finally:
3525 repo.ui.setconfig('ui', 'forcemerge', '', 'graft')
3525 repo.ui.setconfig('ui', 'forcemerge', '', 'graft')
3526 # report any conflicts
3526 # report any conflicts
3527 if stats and stats[3] > 0:
3527 if stats and stats[3] > 0:
3528 # write out state for --continue
3528 # write out state for --continue
3529 nodelines = [repo[rev].hex() + "\n" for rev in revs[pos:]]
3529 nodelines = [repo[rev].hex() + "\n" for rev in revs[pos:]]
3530 repo.vfs.write('graftstate', ''.join(nodelines))
3530 repo.vfs.write('graftstate', ''.join(nodelines))
3531 extra = ''
3531 extra = ''
3532 if opts.get('user'):
3532 if opts.get('user'):
3533 extra += ' --user %s' % util.shellquote(opts['user'])
3533 extra += ' --user %s' % util.shellquote(opts['user'])
3534 if opts.get('date'):
3534 if opts.get('date'):
3535 extra += ' --date %s' % util.shellquote(opts['date'])
3535 extra += ' --date %s' % util.shellquote(opts['date'])
3536 if opts.get('log'):
3536 if opts.get('log'):
3537 extra += ' --log'
3537 extra += ' --log'
3538 hint=_("use 'hg resolve' and 'hg graft --continue%s'") % extra
3538 hint=_("use 'hg resolve' and 'hg graft --continue%s'") % extra
3539 raise error.Abort(
3539 raise error.Abort(
3540 _("unresolved conflicts, can't continue"),
3540 _("unresolved conflicts, can't continue"),
3541 hint=hint)
3541 hint=hint)
3542 else:
3542 else:
3543 cont = False
3543 cont = False
3544
3544
3545 # commit
3545 # commit
3546 node = repo.commit(text=message, user=user,
3546 node = repo.commit(text=message, user=user,
3547 date=date, extra=extra, editor=editor)
3547 date=date, extra=extra, editor=editor)
3548 if node is None:
3548 if node is None:
3549 ui.warn(
3549 ui.warn(
3550 _('note: graft of %d:%s created no changes to commit\n') %
3550 _('note: graft of %d:%s created no changes to commit\n') %
3551 (ctx.rev(), ctx))
3551 (ctx.rev(), ctx))
3552
3552
3553 # remove state when we complete successfully
3553 # remove state when we complete successfully
3554 if not opts.get('dry_run'):
3554 if not opts.get('dry_run'):
3555 util.unlinkpath(repo.join('graftstate'), ignoremissing=True)
3555 util.unlinkpath(repo.join('graftstate'), ignoremissing=True)
3556
3556
3557 return 0
3557 return 0
3558
3558
3559 @command('grep',
3559 @command('grep',
3560 [('0', 'print0', None, _('end fields with NUL')),
3560 [('0', 'print0', None, _('end fields with NUL')),
3561 ('', 'all', None, _('print all revisions that match')),
3561 ('', 'all', None, _('print all revisions that match')),
3562 ('a', 'text', None, _('treat all files as text')),
3562 ('a', 'text', None, _('treat all files as text')),
3563 ('f', 'follow', None,
3563 ('f', 'follow', None,
3564 _('follow changeset history,'
3564 _('follow changeset history,'
3565 ' or file history across copies and renames')),
3565 ' or file history across copies and renames')),
3566 ('i', 'ignore-case', None, _('ignore case when matching')),
3566 ('i', 'ignore-case', None, _('ignore case when matching')),
3567 ('l', 'files-with-matches', None,
3567 ('l', 'files-with-matches', None,
3568 _('print only filenames and revisions that match')),
3568 _('print only filenames and revisions that match')),
3569 ('n', 'line-number', None, _('print matching line numbers')),
3569 ('n', 'line-number', None, _('print matching line numbers')),
3570 ('r', 'rev', [],
3570 ('r', 'rev', [],
3571 _('only search files changed within revision range'), _('REV')),
3571 _('only search files changed within revision range'), _('REV')),
3572 ('u', 'user', None, _('list the author (long with -v)')),
3572 ('u', 'user', None, _('list the author (long with -v)')),
3573 ('d', 'date', None, _('list the date (short with -q)')),
3573 ('d', 'date', None, _('list the date (short with -q)')),
3574 ] + formatteropts + walkopts,
3574 ] + formatteropts + walkopts,
3575 _('[OPTION]... PATTERN [FILE]...'),
3575 _('[OPTION]... PATTERN [FILE]...'),
3576 inferrepo=True)
3576 inferrepo=True)
3577 def grep(ui, repo, pattern, *pats, **opts):
3577 def grep(ui, repo, pattern, *pats, **opts):
3578 """search revision history for a pattern in specified files
3578 """search revision history for a pattern in specified files
3579
3579
3580 Search revision history for a regular expression in the specified
3580 Search revision history for a regular expression in the specified
3581 files or the entire project.
3581 files or the entire project.
3582
3582
3583 By default, grep prints the most recent revision number for each
3583 By default, grep prints the most recent revision number for each
3584 file in which it finds a match. To get it to print every revision
3584 file in which it finds a match. To get it to print every revision
3585 that contains a change in match status ("-" for a match that becomes
3585 that contains a change in match status ("-" for a match that becomes
3586 a non-match, or "+" for a non-match that becomes a match), use the
3586 a non-match, or "+" for a non-match that becomes a match), use the
3587 --all flag.
3587 --all flag.
3588
3588
3589 PATTERN can be any Python (roughly Perl-compatible) regular
3589 PATTERN can be any Python (roughly Perl-compatible) regular
3590 expression.
3590 expression.
3591
3591
3592 If no FILEs are specified (and -f/--follow isn't set), all files in
3592 If no FILEs are specified (and -f/--follow isn't set), all files in
3593 the repository are searched, including those that don't exist in the
3593 the repository are searched, including those that don't exist in the
3594 current branch or have been deleted in a prior changeset.
3594 current branch or have been deleted in a prior changeset.
3595
3595
3596 Returns 0 if a match is found, 1 otherwise.
3596 Returns 0 if a match is found, 1 otherwise.
3597 """
3597 """
3598 reflags = re.M
3598 reflags = re.M
3599 if opts.get('ignore_case'):
3599 if opts.get('ignore_case'):
3600 reflags |= re.I
3600 reflags |= re.I
3601 try:
3601 try:
3602 regexp = util.re.compile(pattern, reflags)
3602 regexp = util.re.compile(pattern, reflags)
3603 except re.error as inst:
3603 except re.error as inst:
3604 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
3604 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
3605 return 1
3605 return 1
3606 sep, eol = ':', '\n'
3606 sep, eol = ':', '\n'
3607 if opts.get('print0'):
3607 if opts.get('print0'):
3608 sep = eol = '\0'
3608 sep = eol = '\0'
3609
3609
3610 getfile = util.lrucachefunc(repo.file)
3610 getfile = util.lrucachefunc(repo.file)
3611
3611
3612 def matchlines(body):
3612 def matchlines(body):
3613 begin = 0
3613 begin = 0
3614 linenum = 0
3614 linenum = 0
3615 while begin < len(body):
3615 while begin < len(body):
3616 match = regexp.search(body, begin)
3616 match = regexp.search(body, begin)
3617 if not match:
3617 if not match:
3618 break
3618 break
3619 mstart, mend = match.span()
3619 mstart, mend = match.span()
3620 linenum += body.count('\n', begin, mstart) + 1
3620 linenum += body.count('\n', begin, mstart) + 1
3621 lstart = body.rfind('\n', begin, mstart) + 1 or begin
3621 lstart = body.rfind('\n', begin, mstart) + 1 or begin
3622 begin = body.find('\n', mend) + 1 or len(body) + 1
3622 begin = body.find('\n', mend) + 1 or len(body) + 1
3623 lend = begin - 1
3623 lend = begin - 1
3624 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
3624 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
3625
3625
3626 class linestate(object):
3626 class linestate(object):
3627 def __init__(self, line, linenum, colstart, colend):
3627 def __init__(self, line, linenum, colstart, colend):
3628 self.line = line
3628 self.line = line
3629 self.linenum = linenum
3629 self.linenum = linenum
3630 self.colstart = colstart
3630 self.colstart = colstart
3631 self.colend = colend
3631 self.colend = colend
3632
3632
3633 def __hash__(self):
3633 def __hash__(self):
3634 return hash((self.linenum, self.line))
3634 return hash((self.linenum, self.line))
3635
3635
3636 def __eq__(self, other):
3636 def __eq__(self, other):
3637 return self.line == other.line
3637 return self.line == other.line
3638
3638
3639 def findpos(self):
3639 def findpos(self):
3640 """Iterate all (start, end) indices of matches"""
3640 """Iterate all (start, end) indices of matches"""
3641 yield self.colstart, self.colend
3641 yield self.colstart, self.colend
3642 p = self.colend
3642 p = self.colend
3643 while p < len(self.line):
3643 while p < len(self.line):
3644 m = regexp.search(self.line, p)
3644 m = regexp.search(self.line, p)
3645 if not m:
3645 if not m:
3646 break
3646 break
3647 yield m.span()
3647 yield m.span()
3648 p = m.end()
3648 p = m.end()
3649
3649
3650 matches = {}
3650 matches = {}
3651 copies = {}
3651 copies = {}
3652 def grepbody(fn, rev, body):
3652 def grepbody(fn, rev, body):
3653 matches[rev].setdefault(fn, [])
3653 matches[rev].setdefault(fn, [])
3654 m = matches[rev][fn]
3654 m = matches[rev][fn]
3655 for lnum, cstart, cend, line in matchlines(body):
3655 for lnum, cstart, cend, line in matchlines(body):
3656 s = linestate(line, lnum, cstart, cend)
3656 s = linestate(line, lnum, cstart, cend)
3657 m.append(s)
3657 m.append(s)
3658
3658
3659 def difflinestates(a, b):
3659 def difflinestates(a, b):
3660 sm = difflib.SequenceMatcher(None, a, b)
3660 sm = difflib.SequenceMatcher(None, a, b)
3661 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
3661 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
3662 if tag == 'insert':
3662 if tag == 'insert':
3663 for i in xrange(blo, bhi):
3663 for i in xrange(blo, bhi):
3664 yield ('+', b[i])
3664 yield ('+', b[i])
3665 elif tag == 'delete':
3665 elif tag == 'delete':
3666 for i in xrange(alo, ahi):
3666 for i in xrange(alo, ahi):
3667 yield ('-', a[i])
3667 yield ('-', a[i])
3668 elif tag == 'replace':
3668 elif tag == 'replace':
3669 for i in xrange(alo, ahi):
3669 for i in xrange(alo, ahi):
3670 yield ('-', a[i])
3670 yield ('-', a[i])
3671 for i in xrange(blo, bhi):
3671 for i in xrange(blo, bhi):
3672 yield ('+', b[i])
3672 yield ('+', b[i])
3673
3673
3674 def display(fm, fn, ctx, pstates, states):
3674 def display(fm, fn, ctx, pstates, states):
3675 rev = ctx.rev()
3675 rev = ctx.rev()
3676 if fm.isplain():
3676 if fm.isplain():
3677 formatuser = ui.shortuser
3677 formatuser = ui.shortuser
3678 else:
3678 else:
3679 formatuser = str
3679 formatuser = str
3680 if ui.quiet:
3680 if ui.quiet:
3681 datefmt = '%Y-%m-%d'
3681 datefmt = '%Y-%m-%d'
3682 else:
3682 else:
3683 datefmt = '%a %b %d %H:%M:%S %Y %1%2'
3683 datefmt = '%a %b %d %H:%M:%S %Y %1%2'
3684 found = False
3684 found = False
3685 @util.cachefunc
3685 @util.cachefunc
3686 def binary():
3686 def binary():
3687 flog = getfile(fn)
3687 flog = getfile(fn)
3688 return util.binary(flog.read(ctx.filenode(fn)))
3688 return util.binary(flog.read(ctx.filenode(fn)))
3689
3689
3690 fieldnamemap = {'filename': 'file', 'linenumber': 'line_number'}
3690 fieldnamemap = {'filename': 'file', 'linenumber': 'line_number'}
3691 if opts.get('all'):
3691 if opts.get('all'):
3692 iter = difflinestates(pstates, states)
3692 iter = difflinestates(pstates, states)
3693 else:
3693 else:
3694 iter = [('', l) for l in states]
3694 iter = [('', l) for l in states]
3695 for change, l in iter:
3695 for change, l in iter:
3696 fm.startitem()
3696 fm.startitem()
3697 fm.data(node=fm.hexfunc(ctx.node()))
3697 fm.data(node=fm.hexfunc(ctx.node()))
3698 cols = [
3698 cols = [
3699 ('filename', fn, True),
3699 ('filename', fn, True),
3700 ('rev', rev, True),
3700 ('rev', rev, True),
3701 ('linenumber', l.linenum, opts.get('line_number')),
3701 ('linenumber', l.linenum, opts.get('line_number')),
3702 ]
3702 ]
3703 if opts.get('all'):
3703 if opts.get('all'):
3704 cols.append(('change', change, True))
3704 cols.append(('change', change, True))
3705 cols.extend([
3705 cols.extend([
3706 ('user', formatuser(ctx.user()), opts.get('user')),
3706 ('user', formatuser(ctx.user()), opts.get('user')),
3707 ('date', fm.formatdate(ctx.date(), datefmt), opts.get('date')),
3707 ('date', fm.formatdate(ctx.date(), datefmt), opts.get('date')),
3708 ])
3708 ])
3709 lastcol = next(name for name, data, cond in reversed(cols) if cond)
3709 lastcol = next(name for name, data, cond in reversed(cols) if cond)
3710 for name, data, cond in cols:
3710 for name, data, cond in cols:
3711 field = fieldnamemap.get(name, name)
3711 field = fieldnamemap.get(name, name)
3712 fm.condwrite(cond, field, '%s', data, label='grep.%s' % name)
3712 fm.condwrite(cond, field, '%s', data, label='grep.%s' % name)
3713 if cond and name != lastcol:
3713 if cond and name != lastcol:
3714 fm.plain(sep, label='grep.sep')
3714 fm.plain(sep, label='grep.sep')
3715 if not opts.get('files_with_matches'):
3715 if not opts.get('files_with_matches'):
3716 fm.plain(sep, label='grep.sep')
3716 fm.plain(sep, label='grep.sep')
3717 if not opts.get('text') and binary():
3717 if not opts.get('text') and binary():
3718 fm.plain(_(" Binary file matches"))
3718 fm.plain(_(" Binary file matches"))
3719 else:
3719 else:
3720 displaymatches(fm.nested('texts'), l)
3720 displaymatches(fm.nested('texts'), l)
3721 fm.plain(eol)
3721 fm.plain(eol)
3722 found = True
3722 found = True
3723 if opts.get('files_with_matches'):
3723 if opts.get('files_with_matches'):
3724 break
3724 break
3725 return found
3725 return found
3726
3726
3727 def displaymatches(fm, l):
3727 def displaymatches(fm, l):
3728 p = 0
3728 p = 0
3729 for s, e in l.findpos():
3729 for s, e in l.findpos():
3730 if p < s:
3730 if p < s:
3731 fm.startitem()
3731 fm.startitem()
3732 fm.write('text', '%s', l.line[p:s])
3732 fm.write('text', '%s', l.line[p:s])
3733 fm.data(matched=False)
3733 fm.data(matched=False)
3734 fm.startitem()
3734 fm.startitem()
3735 fm.write('text', '%s', l.line[s:e], label='grep.match')
3735 fm.write('text', '%s', l.line[s:e], label='grep.match')
3736 fm.data(matched=True)
3736 fm.data(matched=True)
3737 p = e
3737 p = e
3738 if p < len(l.line):
3738 if p < len(l.line):
3739 fm.startitem()
3739 fm.startitem()
3740 fm.write('text', '%s', l.line[p:])
3740 fm.write('text', '%s', l.line[p:])
3741 fm.data(matched=False)
3741 fm.data(matched=False)
3742 fm.end()
3742 fm.end()
3743
3743
3744 skip = {}
3744 skip = {}
3745 revfiles = {}
3745 revfiles = {}
3746 matchfn = scmutil.match(repo[None], pats, opts)
3746 matchfn = scmutil.match(repo[None], pats, opts)
3747 found = False
3747 found = False
3748 follow = opts.get('follow')
3748 follow = opts.get('follow')
3749
3749
3750 def prep(ctx, fns):
3750 def prep(ctx, fns):
3751 rev = ctx.rev()
3751 rev = ctx.rev()
3752 pctx = ctx.p1()
3752 pctx = ctx.p1()
3753 parent = pctx.rev()
3753 parent = pctx.rev()
3754 matches.setdefault(rev, {})
3754 matches.setdefault(rev, {})
3755 matches.setdefault(parent, {})
3755 matches.setdefault(parent, {})
3756 files = revfiles.setdefault(rev, [])
3756 files = revfiles.setdefault(rev, [])
3757 for fn in fns:
3757 for fn in fns:
3758 flog = getfile(fn)
3758 flog = getfile(fn)
3759 try:
3759 try:
3760 fnode = ctx.filenode(fn)
3760 fnode = ctx.filenode(fn)
3761 except error.LookupError:
3761 except error.LookupError:
3762 continue
3762 continue
3763
3763
3764 copied = flog.renamed(fnode)
3764 copied = flog.renamed(fnode)
3765 copy = follow and copied and copied[0]
3765 copy = follow and copied and copied[0]
3766 if copy:
3766 if copy:
3767 copies.setdefault(rev, {})[fn] = copy
3767 copies.setdefault(rev, {})[fn] = copy
3768 if fn in skip:
3768 if fn in skip:
3769 if copy:
3769 if copy:
3770 skip[copy] = True
3770 skip[copy] = True
3771 continue
3771 continue
3772 files.append(fn)
3772 files.append(fn)
3773
3773
3774 if fn not in matches[rev]:
3774 if fn not in matches[rev]:
3775 grepbody(fn, rev, flog.read(fnode))
3775 grepbody(fn, rev, flog.read(fnode))
3776
3776
3777 pfn = copy or fn
3777 pfn = copy or fn
3778 if pfn not in matches[parent]:
3778 if pfn not in matches[parent]:
3779 try:
3779 try:
3780 fnode = pctx.filenode(pfn)
3780 fnode = pctx.filenode(pfn)
3781 grepbody(pfn, parent, flog.read(fnode))
3781 grepbody(pfn, parent, flog.read(fnode))
3782 except error.LookupError:
3782 except error.LookupError:
3783 pass
3783 pass
3784
3784
3785 fm = ui.formatter('grep', opts)
3785 fm = ui.formatter('grep', opts)
3786 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
3786 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
3787 rev = ctx.rev()
3787 rev = ctx.rev()
3788 parent = ctx.p1().rev()
3788 parent = ctx.p1().rev()
3789 for fn in sorted(revfiles.get(rev, [])):
3789 for fn in sorted(revfiles.get(rev, [])):
3790 states = matches[rev][fn]
3790 states = matches[rev][fn]
3791 copy = copies.get(rev, {}).get(fn)
3791 copy = copies.get(rev, {}).get(fn)
3792 if fn in skip:
3792 if fn in skip:
3793 if copy:
3793 if copy:
3794 skip[copy] = True
3794 skip[copy] = True
3795 continue
3795 continue
3796 pstates = matches.get(parent, {}).get(copy or fn, [])
3796 pstates = matches.get(parent, {}).get(copy or fn, [])
3797 if pstates or states:
3797 if pstates or states:
3798 r = display(fm, fn, ctx, pstates, states)
3798 r = display(fm, fn, ctx, pstates, states)
3799 found = found or r
3799 found = found or r
3800 if r and not opts.get('all'):
3800 if r and not opts.get('all'):
3801 skip[fn] = True
3801 skip[fn] = True
3802 if copy:
3802 if copy:
3803 skip[copy] = True
3803 skip[copy] = True
3804 del matches[rev]
3804 del matches[rev]
3805 del revfiles[rev]
3805 del revfiles[rev]
3806 fm.end()
3806 fm.end()
3807
3807
3808 return not found
3808 return not found
3809
3809
3810 @command('heads',
3810 @command('heads',
3811 [('r', 'rev', '',
3811 [('r', 'rev', '',
3812 _('show only heads which are descendants of STARTREV'), _('STARTREV')),
3812 _('show only heads which are descendants of STARTREV'), _('STARTREV')),
3813 ('t', 'topo', False, _('show topological heads only')),
3813 ('t', 'topo', False, _('show topological heads only')),
3814 ('a', 'active', False, _('show active branchheads only (DEPRECATED)')),
3814 ('a', 'active', False, _('show active branchheads only (DEPRECATED)')),
3815 ('c', 'closed', False, _('show normal and closed branch heads')),
3815 ('c', 'closed', False, _('show normal and closed branch heads')),
3816 ] + templateopts,
3816 ] + templateopts,
3817 _('[-ct] [-r STARTREV] [REV]...'))
3817 _('[-ct] [-r STARTREV] [REV]...'))
3818 def heads(ui, repo, *branchrevs, **opts):
3818 def heads(ui, repo, *branchrevs, **opts):
3819 """show branch heads
3819 """show branch heads
3820
3820
3821 With no arguments, show all open branch heads in the repository.
3821 With no arguments, show all open branch heads in the repository.
3822 Branch heads are changesets that have no descendants on the
3822 Branch heads are changesets that have no descendants on the
3823 same branch. They are where development generally takes place and
3823 same branch. They are where development generally takes place and
3824 are the usual targets for update and merge operations.
3824 are the usual targets for update and merge operations.
3825
3825
3826 If one or more REVs are given, only open branch heads on the
3826 If one or more REVs are given, only open branch heads on the
3827 branches associated with the specified changesets are shown. This
3827 branches associated with the specified changesets are shown. This
3828 means that you can use :hg:`heads .` to see the heads on the
3828 means that you can use :hg:`heads .` to see the heads on the
3829 currently checked-out branch.
3829 currently checked-out branch.
3830
3830
3831 If -c/--closed is specified, also show branch heads marked closed
3831 If -c/--closed is specified, also show branch heads marked closed
3832 (see :hg:`commit --close-branch`).
3832 (see :hg:`commit --close-branch`).
3833
3833
3834 If STARTREV is specified, only those heads that are descendants of
3834 If STARTREV is specified, only those heads that are descendants of
3835 STARTREV will be displayed.
3835 STARTREV will be displayed.
3836
3836
3837 If -t/--topo is specified, named branch mechanics will be ignored and only
3837 If -t/--topo is specified, named branch mechanics will be ignored and only
3838 topological heads (changesets with no children) will be shown.
3838 topological heads (changesets with no children) will be shown.
3839
3839
3840 Returns 0 if matching heads are found, 1 if not.
3840 Returns 0 if matching heads are found, 1 if not.
3841 """
3841 """
3842
3842
3843 start = None
3843 start = None
3844 if 'rev' in opts:
3844 if 'rev' in opts:
3845 start = scmutil.revsingle(repo, opts['rev'], None).node()
3845 start = scmutil.revsingle(repo, opts['rev'], None).node()
3846
3846
3847 if opts.get('topo'):
3847 if opts.get('topo'):
3848 heads = [repo[h] for h in repo.heads(start)]
3848 heads = [repo[h] for h in repo.heads(start)]
3849 else:
3849 else:
3850 heads = []
3850 heads = []
3851 for branch in repo.branchmap():
3851 for branch in repo.branchmap():
3852 heads += repo.branchheads(branch, start, opts.get('closed'))
3852 heads += repo.branchheads(branch, start, opts.get('closed'))
3853 heads = [repo[h] for h in heads]
3853 heads = [repo[h] for h in heads]
3854
3854
3855 if branchrevs:
3855 if branchrevs:
3856 branches = set(repo[br].branch() for br in branchrevs)
3856 branches = set(repo[br].branch() for br in branchrevs)
3857 heads = [h for h in heads if h.branch() in branches]
3857 heads = [h for h in heads if h.branch() in branches]
3858
3858
3859 if opts.get('active') and branchrevs:
3859 if opts.get('active') and branchrevs:
3860 dagheads = repo.heads(start)
3860 dagheads = repo.heads(start)
3861 heads = [h for h in heads if h.node() in dagheads]
3861 heads = [h for h in heads if h.node() in dagheads]
3862
3862
3863 if branchrevs:
3863 if branchrevs:
3864 haveheads = set(h.branch() for h in heads)
3864 haveheads = set(h.branch() for h in heads)
3865 if branches - haveheads:
3865 if branches - haveheads:
3866 headless = ', '.join(b for b in branches - haveheads)
3866 headless = ', '.join(b for b in branches - haveheads)
3867 msg = _('no open branch heads found on branches %s')
3867 msg = _('no open branch heads found on branches %s')
3868 if opts.get('rev'):
3868 if opts.get('rev'):
3869 msg += _(' (started at %s)') % opts['rev']
3869 msg += _(' (started at %s)') % opts['rev']
3870 ui.warn((msg + '\n') % headless)
3870 ui.warn((msg + '\n') % headless)
3871
3871
3872 if not heads:
3872 if not heads:
3873 return 1
3873 return 1
3874
3874
3875 heads = sorted(heads, key=lambda x: -x.rev())
3875 heads = sorted(heads, key=lambda x: -x.rev())
3876 displayer = cmdutil.show_changeset(ui, repo, opts)
3876 displayer = cmdutil.show_changeset(ui, repo, opts)
3877 for ctx in heads:
3877 for ctx in heads:
3878 displayer.show(ctx)
3878 displayer.show(ctx)
3879 displayer.close()
3879 displayer.close()
3880
3880
3881 @command('help',
3881 @command('help',
3882 [('e', 'extension', None, _('show only help for extensions')),
3882 [('e', 'extension', None, _('show only help for extensions')),
3883 ('c', 'command', None, _('show only help for commands')),
3883 ('c', 'command', None, _('show only help for commands')),
3884 ('k', 'keyword', None, _('show topics matching keyword')),
3884 ('k', 'keyword', None, _('show topics matching keyword')),
3885 ('s', 'system', [], _('show help for specific platform(s)')),
3885 ('s', 'system', [], _('show help for specific platform(s)')),
3886 ],
3886 ],
3887 _('[-ecks] [TOPIC]'),
3887 _('[-ecks] [TOPIC]'),
3888 norepo=True)
3888 norepo=True)
3889 def help_(ui, name=None, **opts):
3889 def help_(ui, name=None, **opts):
3890 """show help for a given topic or a help overview
3890 """show help for a given topic or a help overview
3891
3891
3892 With no arguments, print a list of commands with short help messages.
3892 With no arguments, print a list of commands with short help messages.
3893
3893
3894 Given a topic, extension, or command name, print help for that
3894 Given a topic, extension, or command name, print help for that
3895 topic.
3895 topic.
3896
3896
3897 Returns 0 if successful.
3897 Returns 0 if successful.
3898 """
3898 """
3899
3899
3900 textwidth = ui.configint('ui', 'textwidth', 78)
3900 textwidth = ui.configint('ui', 'textwidth', 78)
3901 termwidth = ui.termwidth() - 2
3901 termwidth = ui.termwidth() - 2
3902 if textwidth <= 0 or termwidth < textwidth:
3902 if textwidth <= 0 or termwidth < textwidth:
3903 textwidth = termwidth
3903 textwidth = termwidth
3904
3904
3905 keep = opts.get('system') or []
3905 keep = opts.get('system') or []
3906 if len(keep) == 0:
3906 if len(keep) == 0:
3907 if pycompat.sysplatform.startswith('win'):
3907 if pycompat.sysplatform.startswith('win'):
3908 keep.append('windows')
3908 keep.append('windows')
3909 elif pycompat.sysplatform == 'OpenVMS':
3909 elif pycompat.sysplatform == 'OpenVMS':
3910 keep.append('vms')
3910 keep.append('vms')
3911 elif pycompat.sysplatform == 'plan9':
3911 elif pycompat.sysplatform == 'plan9':
3912 keep.append('plan9')
3912 keep.append('plan9')
3913 else:
3913 else:
3914 keep.append('unix')
3914 keep.append('unix')
3915 keep.append(pycompat.sysplatform.lower())
3915 keep.append(pycompat.sysplatform.lower())
3916 if ui.verbose:
3916 if ui.verbose:
3917 keep.append('verbose')
3917 keep.append('verbose')
3918
3918
3919 section = None
3919 section = None
3920 subtopic = None
3920 subtopic = None
3921 if name and '.' in name:
3921 if name and '.' in name:
3922 name, remaining = name.split('.', 1)
3922 name, remaining = name.split('.', 1)
3923 remaining = encoding.lower(remaining)
3923 remaining = encoding.lower(remaining)
3924 if '.' in remaining:
3924 if '.' in remaining:
3925 subtopic, section = remaining.split('.', 1)
3925 subtopic, section = remaining.split('.', 1)
3926 else:
3926 else:
3927 if name in help.subtopics:
3927 if name in help.subtopics:
3928 subtopic = remaining
3928 subtopic = remaining
3929 else:
3929 else:
3930 section = remaining
3930 section = remaining
3931
3931
3932 text = help.help_(ui, name, subtopic=subtopic, **opts)
3932 text = help.help_(ui, name, subtopic=subtopic, **opts)
3933
3933
3934 formatted, pruned = minirst.format(text, textwidth, keep=keep,
3934 formatted, pruned = minirst.format(text, textwidth, keep=keep,
3935 section=section)
3935 section=section)
3936
3936
3937 # We could have been given a weird ".foo" section without a name
3937 # We could have been given a weird ".foo" section without a name
3938 # to look for, or we could have simply failed to found "foo.bar"
3938 # to look for, or we could have simply failed to found "foo.bar"
3939 # because bar isn't a section of foo
3939 # because bar isn't a section of foo
3940 if section and not (formatted and name):
3940 if section and not (formatted and name):
3941 raise error.Abort(_("help section not found"))
3941 raise error.Abort(_("help section not found"))
3942
3942
3943 if 'verbose' in pruned:
3943 if 'verbose' in pruned:
3944 keep.append('omitted')
3944 keep.append('omitted')
3945 else:
3945 else:
3946 keep.append('notomitted')
3946 keep.append('notomitted')
3947 formatted, pruned = minirst.format(text, textwidth, keep=keep,
3947 formatted, pruned = minirst.format(text, textwidth, keep=keep,
3948 section=section)
3948 section=section)
3949 ui.write(formatted)
3949 ui.write(formatted)
3950
3950
3951
3951
3952 @command('identify|id',
3952 @command('identify|id',
3953 [('r', 'rev', '',
3953 [('r', 'rev', '',
3954 _('identify the specified revision'), _('REV')),
3954 _('identify the specified revision'), _('REV')),
3955 ('n', 'num', None, _('show local revision number')),
3955 ('n', 'num', None, _('show local revision number')),
3956 ('i', 'id', None, _('show global revision id')),
3956 ('i', 'id', None, _('show global revision id')),
3957 ('b', 'branch', None, _('show branch')),
3957 ('b', 'branch', None, _('show branch')),
3958 ('t', 'tags', None, _('show tags')),
3958 ('t', 'tags', None, _('show tags')),
3959 ('B', 'bookmarks', None, _('show bookmarks')),
3959 ('B', 'bookmarks', None, _('show bookmarks')),
3960 ] + remoteopts,
3960 ] + remoteopts,
3961 _('[-nibtB] [-r REV] [SOURCE]'),
3961 _('[-nibtB] [-r REV] [SOURCE]'),
3962 optionalrepo=True)
3962 optionalrepo=True)
3963 def identify(ui, repo, source=None, rev=None,
3963 def identify(ui, repo, source=None, rev=None,
3964 num=None, id=None, branch=None, tags=None, bookmarks=None, **opts):
3964 num=None, id=None, branch=None, tags=None, bookmarks=None, **opts):
3965 """identify the working directory or specified revision
3965 """identify the working directory or specified revision
3966
3966
3967 Print a summary identifying the repository state at REV using one or
3967 Print a summary identifying the repository state at REV using one or
3968 two parent hash identifiers, followed by a "+" if the working
3968 two parent hash identifiers, followed by a "+" if the working
3969 directory has uncommitted changes, the branch name (if not default),
3969 directory has uncommitted changes, the branch name (if not default),
3970 a list of tags, and a list of bookmarks.
3970 a list of tags, and a list of bookmarks.
3971
3971
3972 When REV is not given, print a summary of the current state of the
3972 When REV is not given, print a summary of the current state of the
3973 repository.
3973 repository.
3974
3974
3975 Specifying a path to a repository root or Mercurial bundle will
3975 Specifying a path to a repository root or Mercurial bundle will
3976 cause lookup to operate on that repository/bundle.
3976 cause lookup to operate on that repository/bundle.
3977
3977
3978 .. container:: verbose
3978 .. container:: verbose
3979
3979
3980 Examples:
3980 Examples:
3981
3981
3982 - generate a build identifier for the working directory::
3982 - generate a build identifier for the working directory::
3983
3983
3984 hg id --id > build-id.dat
3984 hg id --id > build-id.dat
3985
3985
3986 - find the revision corresponding to a tag::
3986 - find the revision corresponding to a tag::
3987
3987
3988 hg id -n -r 1.3
3988 hg id -n -r 1.3
3989
3989
3990 - check the most recent revision of a remote repository::
3990 - check the most recent revision of a remote repository::
3991
3991
3992 hg id -r tip https://www.mercurial-scm.org/repo/hg/
3992 hg id -r tip https://www.mercurial-scm.org/repo/hg/
3993
3993
3994 See :hg:`log` for generating more information about specific revisions,
3994 See :hg:`log` for generating more information about specific revisions,
3995 including full hash identifiers.
3995 including full hash identifiers.
3996
3996
3997 Returns 0 if successful.
3997 Returns 0 if successful.
3998 """
3998 """
3999
3999
4000 if not repo and not source:
4000 if not repo and not source:
4001 raise error.Abort(_("there is no Mercurial repository here "
4001 raise error.Abort(_("there is no Mercurial repository here "
4002 "(.hg not found)"))
4002 "(.hg not found)"))
4003
4003
4004 if ui.debugflag:
4004 if ui.debugflag:
4005 hexfunc = hex
4005 hexfunc = hex
4006 else:
4006 else:
4007 hexfunc = short
4007 hexfunc = short
4008 default = not (num or id or branch or tags or bookmarks)
4008 default = not (num or id or branch or tags or bookmarks)
4009 output = []
4009 output = []
4010 revs = []
4010 revs = []
4011
4011
4012 if source:
4012 if source:
4013 source, branches = hg.parseurl(ui.expandpath(source))
4013 source, branches = hg.parseurl(ui.expandpath(source))
4014 peer = hg.peer(repo or ui, opts, source) # only pass ui when no repo
4014 peer = hg.peer(repo or ui, opts, source) # only pass ui when no repo
4015 repo = peer.local()
4015 repo = peer.local()
4016 revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
4016 revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
4017
4017
4018 if not repo:
4018 if not repo:
4019 if num or branch or tags:
4019 if num or branch or tags:
4020 raise error.Abort(
4020 raise error.Abort(
4021 _("can't query remote revision number, branch, or tags"))
4021 _("can't query remote revision number, branch, or tags"))
4022 if not rev and revs:
4022 if not rev and revs:
4023 rev = revs[0]
4023 rev = revs[0]
4024 if not rev:
4024 if not rev:
4025 rev = "tip"
4025 rev = "tip"
4026
4026
4027 remoterev = peer.lookup(rev)
4027 remoterev = peer.lookup(rev)
4028 if default or id:
4028 if default or id:
4029 output = [hexfunc(remoterev)]
4029 output = [hexfunc(remoterev)]
4030
4030
4031 def getbms():
4031 def getbms():
4032 bms = []
4032 bms = []
4033
4033
4034 if 'bookmarks' in peer.listkeys('namespaces'):
4034 if 'bookmarks' in peer.listkeys('namespaces'):
4035 hexremoterev = hex(remoterev)
4035 hexremoterev = hex(remoterev)
4036 bms = [bm for bm, bmr in peer.listkeys('bookmarks').iteritems()
4036 bms = [bm for bm, bmr in peer.listkeys('bookmarks').iteritems()
4037 if bmr == hexremoterev]
4037 if bmr == hexremoterev]
4038
4038
4039 return sorted(bms)
4039 return sorted(bms)
4040
4040
4041 if bookmarks:
4041 if bookmarks:
4042 output.extend(getbms())
4042 output.extend(getbms())
4043 elif default and not ui.quiet:
4043 elif default and not ui.quiet:
4044 # multiple bookmarks for a single parent separated by '/'
4044 # multiple bookmarks for a single parent separated by '/'
4045 bm = '/'.join(getbms())
4045 bm = '/'.join(getbms())
4046 if bm:
4046 if bm:
4047 output.append(bm)
4047 output.append(bm)
4048 else:
4048 else:
4049 ctx = scmutil.revsingle(repo, rev, None)
4049 ctx = scmutil.revsingle(repo, rev, None)
4050
4050
4051 if ctx.rev() is None:
4051 if ctx.rev() is None:
4052 ctx = repo[None]
4052 ctx = repo[None]
4053 parents = ctx.parents()
4053 parents = ctx.parents()
4054 taglist = []
4054 taglist = []
4055 for p in parents:
4055 for p in parents:
4056 taglist.extend(p.tags())
4056 taglist.extend(p.tags())
4057
4057
4058 changed = ""
4058 changed = ""
4059 if default or id or num:
4059 if default or id or num:
4060 if (any(repo.status())
4060 if (any(repo.status())
4061 or any(ctx.sub(s).dirty() for s in ctx.substate)):
4061 or any(ctx.sub(s).dirty() for s in ctx.substate)):
4062 changed = '+'
4062 changed = '+'
4063 if default or id:
4063 if default or id:
4064 output = ["%s%s" %
4064 output = ["%s%s" %
4065 ('+'.join([hexfunc(p.node()) for p in parents]), changed)]
4065 ('+'.join([hexfunc(p.node()) for p in parents]), changed)]
4066 if num:
4066 if num:
4067 output.append("%s%s" %
4067 output.append("%s%s" %
4068 ('+'.join([str(p.rev()) for p in parents]), changed))
4068 ('+'.join([str(p.rev()) for p in parents]), changed))
4069 else:
4069 else:
4070 if default or id:
4070 if default or id:
4071 output = [hexfunc(ctx.node())]
4071 output = [hexfunc(ctx.node())]
4072 if num:
4072 if num:
4073 output.append(str(ctx.rev()))
4073 output.append(str(ctx.rev()))
4074 taglist = ctx.tags()
4074 taglist = ctx.tags()
4075
4075
4076 if default and not ui.quiet:
4076 if default and not ui.quiet:
4077 b = ctx.branch()
4077 b = ctx.branch()
4078 if b != 'default':
4078 if b != 'default':
4079 output.append("(%s)" % b)
4079 output.append("(%s)" % b)
4080
4080
4081 # multiple tags for a single parent separated by '/'
4081 # multiple tags for a single parent separated by '/'
4082 t = '/'.join(taglist)
4082 t = '/'.join(taglist)
4083 if t:
4083 if t:
4084 output.append(t)
4084 output.append(t)
4085
4085
4086 # multiple bookmarks for a single parent separated by '/'
4086 # multiple bookmarks for a single parent separated by '/'
4087 bm = '/'.join(ctx.bookmarks())
4087 bm = '/'.join(ctx.bookmarks())
4088 if bm:
4088 if bm:
4089 output.append(bm)
4089 output.append(bm)
4090 else:
4090 else:
4091 if branch:
4091 if branch:
4092 output.append(ctx.branch())
4092 output.append(ctx.branch())
4093
4093
4094 if tags:
4094 if tags:
4095 output.extend(taglist)
4095 output.extend(taglist)
4096
4096
4097 if bookmarks:
4097 if bookmarks:
4098 output.extend(ctx.bookmarks())
4098 output.extend(ctx.bookmarks())
4099
4099
4100 ui.write("%s\n" % ' '.join(output))
4100 ui.write("%s\n" % ' '.join(output))
4101
4101
4102 @command('import|patch',
4102 @command('import|patch',
4103 [('p', 'strip', 1,
4103 [('p', 'strip', 1,
4104 _('directory strip option for patch. This has the same '
4104 _('directory strip option for patch. This has the same '
4105 'meaning as the corresponding patch option'), _('NUM')),
4105 'meaning as the corresponding patch option'), _('NUM')),
4106 ('b', 'base', '', _('base path (DEPRECATED)'), _('PATH')),
4106 ('b', 'base', '', _('base path (DEPRECATED)'), _('PATH')),
4107 ('e', 'edit', False, _('invoke editor on commit messages')),
4107 ('e', 'edit', False, _('invoke editor on commit messages')),
4108 ('f', 'force', None,
4108 ('f', 'force', None,
4109 _('skip check for outstanding uncommitted changes (DEPRECATED)')),
4109 _('skip check for outstanding uncommitted changes (DEPRECATED)')),
4110 ('', 'no-commit', None,
4110 ('', 'no-commit', None,
4111 _("don't commit, just update the working directory")),
4111 _("don't commit, just update the working directory")),
4112 ('', 'bypass', None,
4112 ('', 'bypass', None,
4113 _("apply patch without touching the working directory")),
4113 _("apply patch without touching the working directory")),
4114 ('', 'partial', None,
4114 ('', 'partial', None,
4115 _('commit even if some hunks fail')),
4115 _('commit even if some hunks fail')),
4116 ('', 'exact', None,
4116 ('', 'exact', None,
4117 _('abort if patch would apply lossily')),
4117 _('abort if patch would apply lossily')),
4118 ('', 'prefix', '',
4118 ('', 'prefix', '',
4119 _('apply patch to subdirectory'), _('DIR')),
4119 _('apply patch to subdirectory'), _('DIR')),
4120 ('', 'import-branch', None,
4120 ('', 'import-branch', None,
4121 _('use any branch information in patch (implied by --exact)'))] +
4121 _('use any branch information in patch (implied by --exact)'))] +
4122 commitopts + commitopts2 + similarityopts,
4122 commitopts + commitopts2 + similarityopts,
4123 _('[OPTION]... PATCH...'))
4123 _('[OPTION]... PATCH...'))
4124 def import_(ui, repo, patch1=None, *patches, **opts):
4124 def import_(ui, repo, patch1=None, *patches, **opts):
4125 """import an ordered set of patches
4125 """import an ordered set of patches
4126
4126
4127 Import a list of patches and commit them individually (unless
4127 Import a list of patches and commit them individually (unless
4128 --no-commit is specified).
4128 --no-commit is specified).
4129
4129
4130 To read a patch from standard input, use "-" as the patch name. If
4130 To read a patch from standard input, use "-" as the patch name. If
4131 a URL is specified, the patch will be downloaded from there.
4131 a URL is specified, the patch will be downloaded from there.
4132
4132
4133 Import first applies changes to the working directory (unless
4133 Import first applies changes to the working directory (unless
4134 --bypass is specified), import will abort if there are outstanding
4134 --bypass is specified), import will abort if there are outstanding
4135 changes.
4135 changes.
4136
4136
4137 Use --bypass to apply and commit patches directly to the
4137 Use --bypass to apply and commit patches directly to the
4138 repository, without affecting the working directory. Without
4138 repository, without affecting the working directory. Without
4139 --exact, patches will be applied on top of the working directory
4139 --exact, patches will be applied on top of the working directory
4140 parent revision.
4140 parent revision.
4141
4141
4142 You can import a patch straight from a mail message. Even patches
4142 You can import a patch straight from a mail message. Even patches
4143 as attachments work (to use the body part, it must have type
4143 as attachments work (to use the body part, it must have type
4144 text/plain or text/x-patch). From and Subject headers of email
4144 text/plain or text/x-patch). From and Subject headers of email
4145 message are used as default committer and commit message. All
4145 message are used as default committer and commit message. All
4146 text/plain body parts before first diff are added to the commit
4146 text/plain body parts before first diff are added to the commit
4147 message.
4147 message.
4148
4148
4149 If the imported patch was generated by :hg:`export`, user and
4149 If the imported patch was generated by :hg:`export`, user and
4150 description from patch override values from message headers and
4150 description from patch override values from message headers and
4151 body. Values given on command line with -m/--message and -u/--user
4151 body. Values given on command line with -m/--message and -u/--user
4152 override these.
4152 override these.
4153
4153
4154 If --exact is specified, import will set the working directory to
4154 If --exact is specified, import will set the working directory to
4155 the parent of each patch before applying it, and will abort if the
4155 the parent of each patch before applying it, and will abort if the
4156 resulting changeset has a different ID than the one recorded in
4156 resulting changeset has a different ID than the one recorded in
4157 the patch. This will guard against various ways that portable
4157 the patch. This will guard against various ways that portable
4158 patch formats and mail systems might fail to transfer Mercurial
4158 patch formats and mail systems might fail to transfer Mercurial
4159 data or metadata. See :hg:`bundle` for lossless transmission.
4159 data or metadata. See :hg:`bundle` for lossless transmission.
4160
4160
4161 Use --partial to ensure a changeset will be created from the patch
4161 Use --partial to ensure a changeset will be created from the patch
4162 even if some hunks fail to apply. Hunks that fail to apply will be
4162 even if some hunks fail to apply. Hunks that fail to apply will be
4163 written to a <target-file>.rej file. Conflicts can then be resolved
4163 written to a <target-file>.rej file. Conflicts can then be resolved
4164 by hand before :hg:`commit --amend` is run to update the created
4164 by hand before :hg:`commit --amend` is run to update the created
4165 changeset. This flag exists to let people import patches that
4165 changeset. This flag exists to let people import patches that
4166 partially apply without losing the associated metadata (author,
4166 partially apply without losing the associated metadata (author,
4167 date, description, ...).
4167 date, description, ...).
4168
4168
4169 .. note::
4169 .. note::
4170
4170
4171 When no hunks apply cleanly, :hg:`import --partial` will create
4171 When no hunks apply cleanly, :hg:`import --partial` will create
4172 an empty changeset, importing only the patch metadata.
4172 an empty changeset, importing only the patch metadata.
4173
4173
4174 With -s/--similarity, hg will attempt to discover renames and
4174 With -s/--similarity, hg will attempt to discover renames and
4175 copies in the patch in the same way as :hg:`addremove`.
4175 copies in the patch in the same way as :hg:`addremove`.
4176
4176
4177 It is possible to use external patch programs to perform the patch
4177 It is possible to use external patch programs to perform the patch
4178 by setting the ``ui.patch`` configuration option. For the default
4178 by setting the ``ui.patch`` configuration option. For the default
4179 internal tool, the fuzz can also be configured via ``patch.fuzz``.
4179 internal tool, the fuzz can also be configured via ``patch.fuzz``.
4180 See :hg:`help config` for more information about configuration
4180 See :hg:`help config` for more information about configuration
4181 files and how to use these options.
4181 files and how to use these options.
4182
4182
4183 See :hg:`help dates` for a list of formats valid for -d/--date.
4183 See :hg:`help dates` for a list of formats valid for -d/--date.
4184
4184
4185 .. container:: verbose
4185 .. container:: verbose
4186
4186
4187 Examples:
4187 Examples:
4188
4188
4189 - import a traditional patch from a website and detect renames::
4189 - import a traditional patch from a website and detect renames::
4190
4190
4191 hg import -s 80 http://example.com/bugfix.patch
4191 hg import -s 80 http://example.com/bugfix.patch
4192
4192
4193 - import a changeset from an hgweb server::
4193 - import a changeset from an hgweb server::
4194
4194
4195 hg import https://www.mercurial-scm.org/repo/hg/rev/5ca8c111e9aa
4195 hg import https://www.mercurial-scm.org/repo/hg/rev/5ca8c111e9aa
4196
4196
4197 - import all the patches in an Unix-style mbox::
4197 - import all the patches in an Unix-style mbox::
4198
4198
4199 hg import incoming-patches.mbox
4199 hg import incoming-patches.mbox
4200
4200
4201 - attempt to exactly restore an exported changeset (not always
4201 - attempt to exactly restore an exported changeset (not always
4202 possible)::
4202 possible)::
4203
4203
4204 hg import --exact proposed-fix.patch
4204 hg import --exact proposed-fix.patch
4205
4205
4206 - use an external tool to apply a patch which is too fuzzy for
4206 - use an external tool to apply a patch which is too fuzzy for
4207 the default internal tool.
4207 the default internal tool.
4208
4208
4209 hg import --config ui.patch="patch --merge" fuzzy.patch
4209 hg import --config ui.patch="patch --merge" fuzzy.patch
4210
4210
4211 - change the default fuzzing from 2 to a less strict 7
4211 - change the default fuzzing from 2 to a less strict 7
4212
4212
4213 hg import --config ui.fuzz=7 fuzz.patch
4213 hg import --config ui.fuzz=7 fuzz.patch
4214
4214
4215 Returns 0 on success, 1 on partial success (see --partial).
4215 Returns 0 on success, 1 on partial success (see --partial).
4216 """
4216 """
4217
4217
4218 if not patch1:
4218 if not patch1:
4219 raise error.Abort(_('need at least one patch to import'))
4219 raise error.Abort(_('need at least one patch to import'))
4220
4220
4221 patches = (patch1,) + patches
4221 patches = (patch1,) + patches
4222
4222
4223 date = opts.get('date')
4223 date = opts.get('date')
4224 if date:
4224 if date:
4225 opts['date'] = util.parsedate(date)
4225 opts['date'] = util.parsedate(date)
4226
4226
4227 exact = opts.get('exact')
4227 exact = opts.get('exact')
4228 update = not opts.get('bypass')
4228 update = not opts.get('bypass')
4229 if not update and opts.get('no_commit'):
4229 if not update and opts.get('no_commit'):
4230 raise error.Abort(_('cannot use --no-commit with --bypass'))
4230 raise error.Abort(_('cannot use --no-commit with --bypass'))
4231 try:
4231 try:
4232 sim = float(opts.get('similarity') or 0)
4232 sim = float(opts.get('similarity') or 0)
4233 except ValueError:
4233 except ValueError:
4234 raise error.Abort(_('similarity must be a number'))
4234 raise error.Abort(_('similarity must be a number'))
4235 if sim < 0 or sim > 100:
4235 if sim < 0 or sim > 100:
4236 raise error.Abort(_('similarity must be between 0 and 100'))
4236 raise error.Abort(_('similarity must be between 0 and 100'))
4237 if sim and not update:
4237 if sim and not update:
4238 raise error.Abort(_('cannot use --similarity with --bypass'))
4238 raise error.Abort(_('cannot use --similarity with --bypass'))
4239 if exact:
4239 if exact:
4240 if opts.get('edit'):
4240 if opts.get('edit'):
4241 raise error.Abort(_('cannot use --exact with --edit'))
4241 raise error.Abort(_('cannot use --exact with --edit'))
4242 if opts.get('prefix'):
4242 if opts.get('prefix'):
4243 raise error.Abort(_('cannot use --exact with --prefix'))
4243 raise error.Abort(_('cannot use --exact with --prefix'))
4244
4244
4245 base = opts["base"]
4245 base = opts["base"]
4246 wlock = dsguard = lock = tr = None
4246 wlock = dsguard = lock = tr = None
4247 msgs = []
4247 msgs = []
4248 ret = 0
4248 ret = 0
4249
4249
4250
4250
4251 try:
4251 try:
4252 wlock = repo.wlock()
4252 wlock = repo.wlock()
4253
4253
4254 if update:
4254 if update:
4255 cmdutil.checkunfinished(repo)
4255 cmdutil.checkunfinished(repo)
4256 if (exact or not opts.get('force')):
4256 if (exact or not opts.get('force')):
4257 cmdutil.bailifchanged(repo)
4257 cmdutil.bailifchanged(repo)
4258
4258
4259 if not opts.get('no_commit'):
4259 if not opts.get('no_commit'):
4260 lock = repo.lock()
4260 lock = repo.lock()
4261 tr = repo.transaction('import')
4261 tr = repo.transaction('import')
4262 else:
4262 else:
4263 dsguard = dirstateguard.dirstateguard(repo, 'import')
4263 dsguard = dirstateguard.dirstateguard(repo, 'import')
4264 parents = repo[None].parents()
4264 parents = repo[None].parents()
4265 for patchurl in patches:
4265 for patchurl in patches:
4266 if patchurl == '-':
4266 if patchurl == '-':
4267 ui.status(_('applying patch from stdin\n'))
4267 ui.status(_('applying patch from stdin\n'))
4268 patchfile = ui.fin
4268 patchfile = ui.fin
4269 patchurl = 'stdin' # for error message
4269 patchurl = 'stdin' # for error message
4270 else:
4270 else:
4271 patchurl = os.path.join(base, patchurl)
4271 patchurl = os.path.join(base, patchurl)
4272 ui.status(_('applying %s\n') % patchurl)
4272 ui.status(_('applying %s\n') % patchurl)
4273 patchfile = hg.openpath(ui, patchurl)
4273 patchfile = hg.openpath(ui, patchurl)
4274
4274
4275 haspatch = False
4275 haspatch = False
4276 for hunk in patch.split(patchfile):
4276 for hunk in patch.split(patchfile):
4277 (msg, node, rej) = cmdutil.tryimportone(ui, repo, hunk,
4277 (msg, node, rej) = cmdutil.tryimportone(ui, repo, hunk,
4278 parents, opts,
4278 parents, opts,
4279 msgs, hg.clean)
4279 msgs, hg.clean)
4280 if msg:
4280 if msg:
4281 haspatch = True
4281 haspatch = True
4282 ui.note(msg + '\n')
4282 ui.note(msg + '\n')
4283 if update or exact:
4283 if update or exact:
4284 parents = repo[None].parents()
4284 parents = repo[None].parents()
4285 else:
4285 else:
4286 parents = [repo[node]]
4286 parents = [repo[node]]
4287 if rej:
4287 if rej:
4288 ui.write_err(_("patch applied partially\n"))
4288 ui.write_err(_("patch applied partially\n"))
4289 ui.write_err(_("(fix the .rej files and run "
4289 ui.write_err(_("(fix the .rej files and run "
4290 "`hg commit --amend`)\n"))
4290 "`hg commit --amend`)\n"))
4291 ret = 1
4291 ret = 1
4292 break
4292 break
4293
4293
4294 if not haspatch:
4294 if not haspatch:
4295 raise error.Abort(_('%s: no diffs found') % patchurl)
4295 raise error.Abort(_('%s: no diffs found') % patchurl)
4296
4296
4297 if tr:
4297 if tr:
4298 tr.close()
4298 tr.close()
4299 if msgs:
4299 if msgs:
4300 repo.savecommitmessage('\n* * *\n'.join(msgs))
4300 repo.savecommitmessage('\n* * *\n'.join(msgs))
4301 if dsguard:
4301 if dsguard:
4302 dsguard.close()
4302 dsguard.close()
4303 return ret
4303 return ret
4304 finally:
4304 finally:
4305 if tr:
4305 if tr:
4306 tr.release()
4306 tr.release()
4307 release(lock, dsguard, wlock)
4307 release(lock, dsguard, wlock)
4308
4308
4309 @command('incoming|in',
4309 @command('incoming|in',
4310 [('f', 'force', None,
4310 [('f', 'force', None,
4311 _('run even if remote repository is unrelated')),
4311 _('run even if remote repository is unrelated')),
4312 ('n', 'newest-first', None, _('show newest record first')),
4312 ('n', 'newest-first', None, _('show newest record first')),
4313 ('', 'bundle', '',
4313 ('', 'bundle', '',
4314 _('file to store the bundles into'), _('FILE')),
4314 _('file to store the bundles into'), _('FILE')),
4315 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
4315 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
4316 ('B', 'bookmarks', False, _("compare bookmarks")),
4316 ('B', 'bookmarks', False, _("compare bookmarks")),
4317 ('b', 'branch', [],
4317 ('b', 'branch', [],
4318 _('a specific branch you would like to pull'), _('BRANCH')),
4318 _('a specific branch you would like to pull'), _('BRANCH')),
4319 ] + logopts + remoteopts + subrepoopts,
4319 ] + logopts + remoteopts + subrepoopts,
4320 _('[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'))
4320 _('[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'))
4321 def incoming(ui, repo, source="default", **opts):
4321 def incoming(ui, repo, source="default", **opts):
4322 """show new changesets found in source
4322 """show new changesets found in source
4323
4323
4324 Show new changesets found in the specified path/URL or the default
4324 Show new changesets found in the specified path/URL or the default
4325 pull location. These are the changesets that would have been pulled
4325 pull location. These are the changesets that would have been pulled
4326 if a pull at the time you issued this command.
4326 if a pull at the time you issued this command.
4327
4327
4328 See pull for valid source format details.
4328 See pull for valid source format details.
4329
4329
4330 .. container:: verbose
4330 .. container:: verbose
4331
4331
4332 With -B/--bookmarks, the result of bookmark comparison between
4332 With -B/--bookmarks, the result of bookmark comparison between
4333 local and remote repositories is displayed. With -v/--verbose,
4333 local and remote repositories is displayed. With -v/--verbose,
4334 status is also displayed for each bookmark like below::
4334 status is also displayed for each bookmark like below::
4335
4335
4336 BM1 01234567890a added
4336 BM1 01234567890a added
4337 BM2 1234567890ab advanced
4337 BM2 1234567890ab advanced
4338 BM3 234567890abc diverged
4338 BM3 234567890abc diverged
4339 BM4 34567890abcd changed
4339 BM4 34567890abcd changed
4340
4340
4341 The action taken locally when pulling depends on the
4341 The action taken locally when pulling depends on the
4342 status of each bookmark:
4342 status of each bookmark:
4343
4343
4344 :``added``: pull will create it
4344 :``added``: pull will create it
4345 :``advanced``: pull will update it
4345 :``advanced``: pull will update it
4346 :``diverged``: pull will create a divergent bookmark
4346 :``diverged``: pull will create a divergent bookmark
4347 :``changed``: result depends on remote changesets
4347 :``changed``: result depends on remote changesets
4348
4348
4349 From the point of view of pulling behavior, bookmark
4349 From the point of view of pulling behavior, bookmark
4350 existing only in the remote repository are treated as ``added``,
4350 existing only in the remote repository are treated as ``added``,
4351 even if it is in fact locally deleted.
4351 even if it is in fact locally deleted.
4352
4352
4353 .. container:: verbose
4353 .. container:: verbose
4354
4354
4355 For remote repository, using --bundle avoids downloading the
4355 For remote repository, using --bundle avoids downloading the
4356 changesets twice if the incoming is followed by a pull.
4356 changesets twice if the incoming is followed by a pull.
4357
4357
4358 Examples:
4358 Examples:
4359
4359
4360 - show incoming changes with patches and full description::
4360 - show incoming changes with patches and full description::
4361
4361
4362 hg incoming -vp
4362 hg incoming -vp
4363
4363
4364 - show incoming changes excluding merges, store a bundle::
4364 - show incoming changes excluding merges, store a bundle::
4365
4365
4366 hg in -vpM --bundle incoming.hg
4366 hg in -vpM --bundle incoming.hg
4367 hg pull incoming.hg
4367 hg pull incoming.hg
4368
4368
4369 - briefly list changes inside a bundle::
4369 - briefly list changes inside a bundle::
4370
4370
4371 hg in changes.hg -T "{desc|firstline}\\n"
4371 hg in changes.hg -T "{desc|firstline}\\n"
4372
4372
4373 Returns 0 if there are incoming changes, 1 otherwise.
4373 Returns 0 if there are incoming changes, 1 otherwise.
4374 """
4374 """
4375 if opts.get('graph'):
4375 if opts.get('graph'):
4376 cmdutil.checkunsupportedgraphflags([], opts)
4376 cmdutil.checkunsupportedgraphflags([], opts)
4377 def display(other, chlist, displayer):
4377 def display(other, chlist, displayer):
4378 revdag = cmdutil.graphrevs(other, chlist, opts)
4378 revdag = cmdutil.graphrevs(other, chlist, opts)
4379 cmdutil.displaygraph(ui, repo, revdag, displayer,
4379 cmdutil.displaygraph(ui, repo, revdag, displayer,
4380 graphmod.asciiedges)
4380 graphmod.asciiedges)
4381
4381
4382 hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True)
4382 hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True)
4383 return 0
4383 return 0
4384
4384
4385 if opts.get('bundle') and opts.get('subrepos'):
4385 if opts.get('bundle') and opts.get('subrepos'):
4386 raise error.Abort(_('cannot combine --bundle and --subrepos'))
4386 raise error.Abort(_('cannot combine --bundle and --subrepos'))
4387
4387
4388 if opts.get('bookmarks'):
4388 if opts.get('bookmarks'):
4389 source, branches = hg.parseurl(ui.expandpath(source),
4389 source, branches = hg.parseurl(ui.expandpath(source),
4390 opts.get('branch'))
4390 opts.get('branch'))
4391 other = hg.peer(repo, opts, source)
4391 other = hg.peer(repo, opts, source)
4392 if 'bookmarks' not in other.listkeys('namespaces'):
4392 if 'bookmarks' not in other.listkeys('namespaces'):
4393 ui.warn(_("remote doesn't support bookmarks\n"))
4393 ui.warn(_("remote doesn't support bookmarks\n"))
4394 return 0
4394 return 0
4395 ui.status(_('comparing with %s\n') % util.hidepassword(source))
4395 ui.status(_('comparing with %s\n') % util.hidepassword(source))
4396 return bookmarks.incoming(ui, repo, other)
4396 return bookmarks.incoming(ui, repo, other)
4397
4397
4398 repo._subtoppath = ui.expandpath(source)
4398 repo._subtoppath = ui.expandpath(source)
4399 try:
4399 try:
4400 return hg.incoming(ui, repo, source, opts)
4400 return hg.incoming(ui, repo, source, opts)
4401 finally:
4401 finally:
4402 del repo._subtoppath
4402 del repo._subtoppath
4403
4403
4404
4404
4405 @command('^init', remoteopts, _('[-e CMD] [--remotecmd CMD] [DEST]'),
4405 @command('^init', remoteopts, _('[-e CMD] [--remotecmd CMD] [DEST]'),
4406 norepo=True)
4406 norepo=True)
4407 def init(ui, dest=".", **opts):
4407 def init(ui, dest=".", **opts):
4408 """create a new repository in the given directory
4408 """create a new repository in the given directory
4409
4409
4410 Initialize a new repository in the given directory. If the given
4410 Initialize a new repository in the given directory. If the given
4411 directory does not exist, it will be created.
4411 directory does not exist, it will be created.
4412
4412
4413 If no directory is given, the current directory is used.
4413 If no directory is given, the current directory is used.
4414
4414
4415 It is possible to specify an ``ssh://`` URL as the destination.
4415 It is possible to specify an ``ssh://`` URL as the destination.
4416 See :hg:`help urls` for more information.
4416 See :hg:`help urls` for more information.
4417
4417
4418 Returns 0 on success.
4418 Returns 0 on success.
4419 """
4419 """
4420 hg.peer(ui, opts, ui.expandpath(dest), create=True)
4420 hg.peer(ui, opts, ui.expandpath(dest), create=True)
4421
4421
4422 @command('locate',
4422 @command('locate',
4423 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
4423 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
4424 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
4424 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
4425 ('f', 'fullpath', None, _('print complete paths from the filesystem root')),
4425 ('f', 'fullpath', None, _('print complete paths from the filesystem root')),
4426 ] + walkopts,
4426 ] + walkopts,
4427 _('[OPTION]... [PATTERN]...'))
4427 _('[OPTION]... [PATTERN]...'))
4428 def locate(ui, repo, *pats, **opts):
4428 def locate(ui, repo, *pats, **opts):
4429 """locate files matching specific patterns (DEPRECATED)
4429 """locate files matching specific patterns (DEPRECATED)
4430
4430
4431 Print files under Mercurial control in the working directory whose
4431 Print files under Mercurial control in the working directory whose
4432 names match the given patterns.
4432 names match the given patterns.
4433
4433
4434 By default, this command searches all directories in the working
4434 By default, this command searches all directories in the working
4435 directory. To search just the current directory and its
4435 directory. To search just the current directory and its
4436 subdirectories, use "--include .".
4436 subdirectories, use "--include .".
4437
4437
4438 If no patterns are given to match, this command prints the names
4438 If no patterns are given to match, this command prints the names
4439 of all files under Mercurial control in the working directory.
4439 of all files under Mercurial control in the working directory.
4440
4440
4441 If you want to feed the output of this command into the "xargs"
4441 If you want to feed the output of this command into the "xargs"
4442 command, use the -0 option to both this command and "xargs". This
4442 command, use the -0 option to both this command and "xargs". This
4443 will avoid the problem of "xargs" treating single filenames that
4443 will avoid the problem of "xargs" treating single filenames that
4444 contain whitespace as multiple filenames.
4444 contain whitespace as multiple filenames.
4445
4445
4446 See :hg:`help files` for a more versatile command.
4446 See :hg:`help files` for a more versatile command.
4447
4447
4448 Returns 0 if a match is found, 1 otherwise.
4448 Returns 0 if a match is found, 1 otherwise.
4449 """
4449 """
4450 if opts.get('print0'):
4450 if opts.get('print0'):
4451 end = '\0'
4451 end = '\0'
4452 else:
4452 else:
4453 end = '\n'
4453 end = '\n'
4454 rev = scmutil.revsingle(repo, opts.get('rev'), None).node()
4454 rev = scmutil.revsingle(repo, opts.get('rev'), None).node()
4455
4455
4456 ret = 1
4456 ret = 1
4457 ctx = repo[rev]
4457 ctx = repo[rev]
4458 m = scmutil.match(ctx, pats, opts, default='relglob',
4458 m = scmutil.match(ctx, pats, opts, default='relglob',
4459 badfn=lambda x, y: False)
4459 badfn=lambda x, y: False)
4460
4460
4461 for abs in ctx.matches(m):
4461 for abs in ctx.matches(m):
4462 if opts.get('fullpath'):
4462 if opts.get('fullpath'):
4463 ui.write(repo.wjoin(abs), end)
4463 ui.write(repo.wjoin(abs), end)
4464 else:
4464 else:
4465 ui.write(((pats and m.rel(abs)) or abs), end)
4465 ui.write(((pats and m.rel(abs)) or abs), end)
4466 ret = 0
4466 ret = 0
4467
4467
4468 return ret
4468 return ret
4469
4469
4470 @command('^log|history',
4470 @command('^log|history',
4471 [('f', 'follow', None,
4471 [('f', 'follow', None,
4472 _('follow changeset history, or file history across copies and renames')),
4472 _('follow changeset history, or file history across copies and renames')),
4473 ('', 'follow-first', None,
4473 ('', 'follow-first', None,
4474 _('only follow the first parent of merge changesets (DEPRECATED)')),
4474 _('only follow the first parent of merge changesets (DEPRECATED)')),
4475 ('d', 'date', '', _('show revisions matching date spec'), _('DATE')),
4475 ('d', 'date', '', _('show revisions matching date spec'), _('DATE')),
4476 ('C', 'copies', None, _('show copied files')),
4476 ('C', 'copies', None, _('show copied files')),
4477 ('k', 'keyword', [],
4477 ('k', 'keyword', [],
4478 _('do case-insensitive search for a given text'), _('TEXT')),
4478 _('do case-insensitive search for a given text'), _('TEXT')),
4479 ('r', 'rev', [], _('show the specified revision or revset'), _('REV')),
4479 ('r', 'rev', [], _('show the specified revision or revset'), _('REV')),
4480 ('', 'removed', None, _('include revisions where files were removed')),
4480 ('', 'removed', None, _('include revisions where files were removed')),
4481 ('m', 'only-merges', None, _('show only merges (DEPRECATED)')),
4481 ('m', 'only-merges', None, _('show only merges (DEPRECATED)')),
4482 ('u', 'user', [], _('revisions committed by user'), _('USER')),
4482 ('u', 'user', [], _('revisions committed by user'), _('USER')),
4483 ('', 'only-branch', [],
4483 ('', 'only-branch', [],
4484 _('show only changesets within the given named branch (DEPRECATED)'),
4484 _('show only changesets within the given named branch (DEPRECATED)'),
4485 _('BRANCH')),
4485 _('BRANCH')),
4486 ('b', 'branch', [],
4486 ('b', 'branch', [],
4487 _('show changesets within the given named branch'), _('BRANCH')),
4487 _('show changesets within the given named branch'), _('BRANCH')),
4488 ('P', 'prune', [],
4488 ('P', 'prune', [],
4489 _('do not display revision or any of its ancestors'), _('REV')),
4489 _('do not display revision or any of its ancestors'), _('REV')),
4490 ] + logopts + walkopts,
4490 ] + logopts + walkopts,
4491 _('[OPTION]... [FILE]'),
4491 _('[OPTION]... [FILE]'),
4492 inferrepo=True)
4492 inferrepo=True)
4493 def log(ui, repo, *pats, **opts):
4493 def log(ui, repo, *pats, **opts):
4494 """show revision history of entire repository or files
4494 """show revision history of entire repository or files
4495
4495
4496 Print the revision history of the specified files or the entire
4496 Print the revision history of the specified files or the entire
4497 project.
4497 project.
4498
4498
4499 If no revision range is specified, the default is ``tip:0`` unless
4499 If no revision range is specified, the default is ``tip:0`` unless
4500 --follow is set, in which case the working directory parent is
4500 --follow is set, in which case the working directory parent is
4501 used as the starting revision.
4501 used as the starting revision.
4502
4502
4503 File history is shown without following rename or copy history of
4503 File history is shown without following rename or copy history of
4504 files. Use -f/--follow with a filename to follow history across
4504 files. Use -f/--follow with a filename to follow history across
4505 renames and copies. --follow without a filename will only show
4505 renames and copies. --follow without a filename will only show
4506 ancestors or descendants of the starting revision.
4506 ancestors or descendants of the starting revision.
4507
4507
4508 By default this command prints revision number and changeset id,
4508 By default this command prints revision number and changeset id,
4509 tags, non-trivial parents, user, date and time, and a summary for
4509 tags, non-trivial parents, user, date and time, and a summary for
4510 each commit. When the -v/--verbose switch is used, the list of
4510 each commit. When the -v/--verbose switch is used, the list of
4511 changed files and full commit message are shown.
4511 changed files and full commit message are shown.
4512
4512
4513 With --graph the revisions are shown as an ASCII art DAG with the most
4513 With --graph the revisions are shown as an ASCII art DAG with the most
4514 recent changeset at the top.
4514 recent changeset at the top.
4515 'o' is a changeset, '@' is a working directory parent, 'x' is obsolete,
4515 'o' is a changeset, '@' is a working directory parent, 'x' is obsolete,
4516 and '+' represents a fork where the changeset from the lines below is a
4516 and '+' represents a fork where the changeset from the lines below is a
4517 parent of the 'o' merge on the same line.
4517 parent of the 'o' merge on the same line.
4518
4518
4519 .. note::
4519 .. note::
4520
4520
4521 :hg:`log --patch` may generate unexpected diff output for merge
4521 :hg:`log --patch` may generate unexpected diff output for merge
4522 changesets, as it will only compare the merge changeset against
4522 changesets, as it will only compare the merge changeset against
4523 its first parent. Also, only files different from BOTH parents
4523 its first parent. Also, only files different from BOTH parents
4524 will appear in files:.
4524 will appear in files:.
4525
4525
4526 .. note::
4526 .. note::
4527
4527
4528 For performance reasons, :hg:`log FILE` may omit duplicate changes
4528 For performance reasons, :hg:`log FILE` may omit duplicate changes
4529 made on branches and will not show removals or mode changes. To
4529 made on branches and will not show removals or mode changes. To
4530 see all such changes, use the --removed switch.
4530 see all such changes, use the --removed switch.
4531
4531
4532 .. container:: verbose
4532 .. container:: verbose
4533
4533
4534 Some examples:
4534 Some examples:
4535
4535
4536 - changesets with full descriptions and file lists::
4536 - changesets with full descriptions and file lists::
4537
4537
4538 hg log -v
4538 hg log -v
4539
4539
4540 - changesets ancestral to the working directory::
4540 - changesets ancestral to the working directory::
4541
4541
4542 hg log -f
4542 hg log -f
4543
4543
4544 - last 10 commits on the current branch::
4544 - last 10 commits on the current branch::
4545
4545
4546 hg log -l 10 -b .
4546 hg log -l 10 -b .
4547
4547
4548 - changesets showing all modifications of a file, including removals::
4548 - changesets showing all modifications of a file, including removals::
4549
4549
4550 hg log --removed file.c
4550 hg log --removed file.c
4551
4551
4552 - all changesets that touch a directory, with diffs, excluding merges::
4552 - all changesets that touch a directory, with diffs, excluding merges::
4553
4553
4554 hg log -Mp lib/
4554 hg log -Mp lib/
4555
4555
4556 - all revision numbers that match a keyword::
4556 - all revision numbers that match a keyword::
4557
4557
4558 hg log -k bug --template "{rev}\\n"
4558 hg log -k bug --template "{rev}\\n"
4559
4559
4560 - the full hash identifier of the working directory parent::
4560 - the full hash identifier of the working directory parent::
4561
4561
4562 hg log -r . --template "{node}\\n"
4562 hg log -r . --template "{node}\\n"
4563
4563
4564 - list available log templates::
4564 - list available log templates::
4565
4565
4566 hg log -T list
4566 hg log -T list
4567
4567
4568 - check if a given changeset is included in a tagged release::
4568 - check if a given changeset is included in a tagged release::
4569
4569
4570 hg log -r "a21ccf and ancestor(1.9)"
4570 hg log -r "a21ccf and ancestor(1.9)"
4571
4571
4572 - find all changesets by some user in a date range::
4572 - find all changesets by some user in a date range::
4573
4573
4574 hg log -k alice -d "may 2008 to jul 2008"
4574 hg log -k alice -d "may 2008 to jul 2008"
4575
4575
4576 - summary of all changesets after the last tag::
4576 - summary of all changesets after the last tag::
4577
4577
4578 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
4578 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
4579
4579
4580 See :hg:`help dates` for a list of formats valid for -d/--date.
4580 See :hg:`help dates` for a list of formats valid for -d/--date.
4581
4581
4582 See :hg:`help revisions` for more about specifying and ordering
4582 See :hg:`help revisions` for more about specifying and ordering
4583 revisions.
4583 revisions.
4584
4584
4585 See :hg:`help templates` for more about pre-packaged styles and
4585 See :hg:`help templates` for more about pre-packaged styles and
4586 specifying custom templates.
4586 specifying custom templates.
4587
4587
4588 Returns 0 on success.
4588 Returns 0 on success.
4589
4589
4590 """
4590 """
4591 if opts.get('follow') and opts.get('rev'):
4591 if opts.get('follow') and opts.get('rev'):
4592 opts['rev'] = [revset.formatspec('reverse(::%lr)', opts.get('rev'))]
4592 opts['rev'] = [revset.formatspec('reverse(::%lr)', opts.get('rev'))]
4593 del opts['follow']
4593 del opts['follow']
4594
4594
4595 if opts.get('graph'):
4595 if opts.get('graph'):
4596 return cmdutil.graphlog(ui, repo, *pats, **opts)
4596 return cmdutil.graphlog(ui, repo, *pats, **opts)
4597
4597
4598 revs, expr, filematcher = cmdutil.getlogrevs(repo, pats, opts)
4598 revs, expr, filematcher = cmdutil.getlogrevs(repo, pats, opts)
4599 limit = cmdutil.loglimit(opts)
4599 limit = cmdutil.loglimit(opts)
4600 count = 0
4600 count = 0
4601
4601
4602 getrenamed = None
4602 getrenamed = None
4603 if opts.get('copies'):
4603 if opts.get('copies'):
4604 endrev = None
4604 endrev = None
4605 if opts.get('rev'):
4605 if opts.get('rev'):
4606 endrev = scmutil.revrange(repo, opts.get('rev')).max() + 1
4606 endrev = scmutil.revrange(repo, opts.get('rev')).max() + 1
4607 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
4607 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
4608
4608
4609 displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
4609 displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
4610 for rev in revs:
4610 for rev in revs:
4611 if count == limit:
4611 if count == limit:
4612 break
4612 break
4613 ctx = repo[rev]
4613 ctx = repo[rev]
4614 copies = None
4614 copies = None
4615 if getrenamed is not None and rev:
4615 if getrenamed is not None and rev:
4616 copies = []
4616 copies = []
4617 for fn in ctx.files():
4617 for fn in ctx.files():
4618 rename = getrenamed(fn, rev)
4618 rename = getrenamed(fn, rev)
4619 if rename:
4619 if rename:
4620 copies.append((fn, rename[0]))
4620 copies.append((fn, rename[0]))
4621 if filematcher:
4621 if filematcher:
4622 revmatchfn = filematcher(ctx.rev())
4622 revmatchfn = filematcher(ctx.rev())
4623 else:
4623 else:
4624 revmatchfn = None
4624 revmatchfn = None
4625 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
4625 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
4626 if displayer.flush(ctx):
4626 if displayer.flush(ctx):
4627 count += 1
4627 count += 1
4628
4628
4629 displayer.close()
4629 displayer.close()
4630
4630
4631 @command('manifest',
4631 @command('manifest',
4632 [('r', 'rev', '', _('revision to display'), _('REV')),
4632 [('r', 'rev', '', _('revision to display'), _('REV')),
4633 ('', 'all', False, _("list files from all revisions"))]
4633 ('', 'all', False, _("list files from all revisions"))]
4634 + formatteropts,
4634 + formatteropts,
4635 _('[-r REV]'))
4635 _('[-r REV]'))
4636 def manifest(ui, repo, node=None, rev=None, **opts):
4636 def manifest(ui, repo, node=None, rev=None, **opts):
4637 """output the current or given revision of the project manifest
4637 """output the current or given revision of the project manifest
4638
4638
4639 Print a list of version controlled files for the given revision.
4639 Print a list of version controlled files for the given revision.
4640 If no revision is given, the first parent of the working directory
4640 If no revision is given, the first parent of the working directory
4641 is used, or the null revision if no revision is checked out.
4641 is used, or the null revision if no revision is checked out.
4642
4642
4643 With -v, print file permissions, symlink and executable bits.
4643 With -v, print file permissions, symlink and executable bits.
4644 With --debug, print file revision hashes.
4644 With --debug, print file revision hashes.
4645
4645
4646 If option --all is specified, the list of all files from all revisions
4646 If option --all is specified, the list of all files from all revisions
4647 is printed. This includes deleted and renamed files.
4647 is printed. This includes deleted and renamed files.
4648
4648
4649 Returns 0 on success.
4649 Returns 0 on success.
4650 """
4650 """
4651
4651
4652 fm = ui.formatter('manifest', opts)
4652 fm = ui.formatter('manifest', opts)
4653
4653
4654 if opts.get('all'):
4654 if opts.get('all'):
4655 if rev or node:
4655 if rev or node:
4656 raise error.Abort(_("can't specify a revision with --all"))
4656 raise error.Abort(_("can't specify a revision with --all"))
4657
4657
4658 res = []
4658 res = []
4659 prefix = "data/"
4659 prefix = "data/"
4660 suffix = ".i"
4660 suffix = ".i"
4661 plen = len(prefix)
4661 plen = len(prefix)
4662 slen = len(suffix)
4662 slen = len(suffix)
4663 with repo.lock():
4663 with repo.lock():
4664 for fn, b, size in repo.store.datafiles():
4664 for fn, b, size in repo.store.datafiles():
4665 if size != 0 and fn[-slen:] == suffix and fn[:plen] == prefix:
4665 if size != 0 and fn[-slen:] == suffix and fn[:plen] == prefix:
4666 res.append(fn[plen:-slen])
4666 res.append(fn[plen:-slen])
4667 for f in res:
4667 for f in res:
4668 fm.startitem()
4668 fm.startitem()
4669 fm.write("path", '%s\n', f)
4669 fm.write("path", '%s\n', f)
4670 fm.end()
4670 fm.end()
4671 return
4671 return
4672
4672
4673 if rev and node:
4673 if rev and node:
4674 raise error.Abort(_("please specify just one revision"))
4674 raise error.Abort(_("please specify just one revision"))
4675
4675
4676 if not node:
4676 if not node:
4677 node = rev
4677 node = rev
4678
4678
4679 char = {'l': '@', 'x': '*', '': ''}
4679 char = {'l': '@', 'x': '*', '': ''}
4680 mode = {'l': '644', 'x': '755', '': '644'}
4680 mode = {'l': '644', 'x': '755', '': '644'}
4681 ctx = scmutil.revsingle(repo, node)
4681 ctx = scmutil.revsingle(repo, node)
4682 mf = ctx.manifest()
4682 mf = ctx.manifest()
4683 for f in ctx:
4683 for f in ctx:
4684 fm.startitem()
4684 fm.startitem()
4685 fl = ctx[f].flags()
4685 fl = ctx[f].flags()
4686 fm.condwrite(ui.debugflag, 'hash', '%s ', hex(mf[f]))
4686 fm.condwrite(ui.debugflag, 'hash', '%s ', hex(mf[f]))
4687 fm.condwrite(ui.verbose, 'mode type', '%s %1s ', mode[fl], char[fl])
4687 fm.condwrite(ui.verbose, 'mode type', '%s %1s ', mode[fl], char[fl])
4688 fm.write('path', '%s\n', f)
4688 fm.write('path', '%s\n', f)
4689 fm.end()
4689 fm.end()
4690
4690
4691 @command('^merge',
4691 @command('^merge',
4692 [('f', 'force', None,
4692 [('f', 'force', None,
4693 _('force a merge including outstanding changes (DEPRECATED)')),
4693 _('force a merge including outstanding changes (DEPRECATED)')),
4694 ('r', 'rev', '', _('revision to merge'), _('REV')),
4694 ('r', 'rev', '', _('revision to merge'), _('REV')),
4695 ('P', 'preview', None,
4695 ('P', 'preview', None,
4696 _('review revisions to merge (no merge is performed)'))
4696 _('review revisions to merge (no merge is performed)'))
4697 ] + mergetoolopts,
4697 ] + mergetoolopts,
4698 _('[-P] [[-r] REV]'))
4698 _('[-P] [[-r] REV]'))
4699 def merge(ui, repo, node=None, **opts):
4699 def merge(ui, repo, node=None, **opts):
4700 """merge another revision into working directory
4700 """merge another revision into working directory
4701
4701
4702 The current working directory is updated with all changes made in
4702 The current working directory is updated with all changes made in
4703 the requested revision since the last common predecessor revision.
4703 the requested revision since the last common predecessor revision.
4704
4704
4705 Files that changed between either parent are marked as changed for
4705 Files that changed between either parent are marked as changed for
4706 the next commit and a commit must be performed before any further
4706 the next commit and a commit must be performed before any further
4707 updates to the repository are allowed. The next commit will have
4707 updates to the repository are allowed. The next commit will have
4708 two parents.
4708 two parents.
4709
4709
4710 ``--tool`` can be used to specify the merge tool used for file
4710 ``--tool`` can be used to specify the merge tool used for file
4711 merges. It overrides the HGMERGE environment variable and your
4711 merges. It overrides the HGMERGE environment variable and your
4712 configuration files. See :hg:`help merge-tools` for options.
4712 configuration files. See :hg:`help merge-tools` for options.
4713
4713
4714 If no revision is specified, the working directory's parent is a
4714 If no revision is specified, the working directory's parent is a
4715 head revision, and the current branch contains exactly one other
4715 head revision, and the current branch contains exactly one other
4716 head, the other head is merged with by default. Otherwise, an
4716 head, the other head is merged with by default. Otherwise, an
4717 explicit revision with which to merge with must be provided.
4717 explicit revision with which to merge with must be provided.
4718
4718
4719 See :hg:`help resolve` for information on handling file conflicts.
4719 See :hg:`help resolve` for information on handling file conflicts.
4720
4720
4721 To undo an uncommitted merge, use :hg:`update --clean .` which
4721 To undo an uncommitted merge, use :hg:`update --clean .` which
4722 will check out a clean copy of the original merge parent, losing
4722 will check out a clean copy of the original merge parent, losing
4723 all changes.
4723 all changes.
4724
4724
4725 Returns 0 on success, 1 if there are unresolved files.
4725 Returns 0 on success, 1 if there are unresolved files.
4726 """
4726 """
4727
4727
4728 if opts.get('rev') and node:
4728 if opts.get('rev') and node:
4729 raise error.Abort(_("please specify just one revision"))
4729 raise error.Abort(_("please specify just one revision"))
4730 if not node:
4730 if not node:
4731 node = opts.get('rev')
4731 node = opts.get('rev')
4732
4732
4733 if node:
4733 if node:
4734 node = scmutil.revsingle(repo, node).node()
4734 node = scmutil.revsingle(repo, node).node()
4735
4735
4736 if not node:
4736 if not node:
4737 node = repo[destutil.destmerge(repo)].node()
4737 node = repo[destutil.destmerge(repo)].node()
4738
4738
4739 if opts.get('preview'):
4739 if opts.get('preview'):
4740 # find nodes that are ancestors of p2 but not of p1
4740 # find nodes that are ancestors of p2 but not of p1
4741 p1 = repo.lookup('.')
4741 p1 = repo.lookup('.')
4742 p2 = repo.lookup(node)
4742 p2 = repo.lookup(node)
4743 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
4743 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
4744
4744
4745 displayer = cmdutil.show_changeset(ui, repo, opts)
4745 displayer = cmdutil.show_changeset(ui, repo, opts)
4746 for node in nodes:
4746 for node in nodes:
4747 displayer.show(repo[node])
4747 displayer.show(repo[node])
4748 displayer.close()
4748 displayer.close()
4749 return 0
4749 return 0
4750
4750
4751 try:
4751 try:
4752 # ui.forcemerge is an internal variable, do not document
4752 # ui.forcemerge is an internal variable, do not document
4753 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''), 'merge')
4753 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''), 'merge')
4754 force = opts.get('force')
4754 force = opts.get('force')
4755 labels = ['working copy', 'merge rev']
4755 labels = ['working copy', 'merge rev']
4756 return hg.merge(repo, node, force=force, mergeforce=force,
4756 return hg.merge(repo, node, force=force, mergeforce=force,
4757 labels=labels)
4757 labels=labels)
4758 finally:
4758 finally:
4759 ui.setconfig('ui', 'forcemerge', '', 'merge')
4759 ui.setconfig('ui', 'forcemerge', '', 'merge')
4760
4760
4761 @command('outgoing|out',
4761 @command('outgoing|out',
4762 [('f', 'force', None, _('run even when the destination is unrelated')),
4762 [('f', 'force', None, _('run even when the destination is unrelated')),
4763 ('r', 'rev', [],
4763 ('r', 'rev', [],
4764 _('a changeset intended to be included in the destination'), _('REV')),
4764 _('a changeset intended to be included in the destination'), _('REV')),
4765 ('n', 'newest-first', None, _('show newest record first')),
4765 ('n', 'newest-first', None, _('show newest record first')),
4766 ('B', 'bookmarks', False, _('compare bookmarks')),
4766 ('B', 'bookmarks', False, _('compare bookmarks')),
4767 ('b', 'branch', [], _('a specific branch you would like to push'),
4767 ('b', 'branch', [], _('a specific branch you would like to push'),
4768 _('BRANCH')),
4768 _('BRANCH')),
4769 ] + logopts + remoteopts + subrepoopts,
4769 ] + logopts + remoteopts + subrepoopts,
4770 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]'))
4770 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]'))
4771 def outgoing(ui, repo, dest=None, **opts):
4771 def outgoing(ui, repo, dest=None, **opts):
4772 """show changesets not found in the destination
4772 """show changesets not found in the destination
4773
4773
4774 Show changesets not found in the specified destination repository
4774 Show changesets not found in the specified destination repository
4775 or the default push location. These are the changesets that would
4775 or the default push location. These are the changesets that would
4776 be pushed if a push was requested.
4776 be pushed if a push was requested.
4777
4777
4778 See pull for details of valid destination formats.
4778 See pull for details of valid destination formats.
4779
4779
4780 .. container:: verbose
4780 .. container:: verbose
4781
4781
4782 With -B/--bookmarks, the result of bookmark comparison between
4782 With -B/--bookmarks, the result of bookmark comparison between
4783 local and remote repositories is displayed. With -v/--verbose,
4783 local and remote repositories is displayed. With -v/--verbose,
4784 status is also displayed for each bookmark like below::
4784 status is also displayed for each bookmark like below::
4785
4785
4786 BM1 01234567890a added
4786 BM1 01234567890a added
4787 BM2 deleted
4787 BM2 deleted
4788 BM3 234567890abc advanced
4788 BM3 234567890abc advanced
4789 BM4 34567890abcd diverged
4789 BM4 34567890abcd diverged
4790 BM5 4567890abcde changed
4790 BM5 4567890abcde changed
4791
4791
4792 The action taken when pushing depends on the
4792 The action taken when pushing depends on the
4793 status of each bookmark:
4793 status of each bookmark:
4794
4794
4795 :``added``: push with ``-B`` will create it
4795 :``added``: push with ``-B`` will create it
4796 :``deleted``: push with ``-B`` will delete it
4796 :``deleted``: push with ``-B`` will delete it
4797 :``advanced``: push will update it
4797 :``advanced``: push will update it
4798 :``diverged``: push with ``-B`` will update it
4798 :``diverged``: push with ``-B`` will update it
4799 :``changed``: push with ``-B`` will update it
4799 :``changed``: push with ``-B`` will update it
4800
4800
4801 From the point of view of pushing behavior, bookmarks
4801 From the point of view of pushing behavior, bookmarks
4802 existing only in the remote repository are treated as
4802 existing only in the remote repository are treated as
4803 ``deleted``, even if it is in fact added remotely.
4803 ``deleted``, even if it is in fact added remotely.
4804
4804
4805 Returns 0 if there are outgoing changes, 1 otherwise.
4805 Returns 0 if there are outgoing changes, 1 otherwise.
4806 """
4806 """
4807 if opts.get('graph'):
4807 if opts.get('graph'):
4808 cmdutil.checkunsupportedgraphflags([], opts)
4808 cmdutil.checkunsupportedgraphflags([], opts)
4809 o, other = hg._outgoing(ui, repo, dest, opts)
4809 o, other = hg._outgoing(ui, repo, dest, opts)
4810 if not o:
4810 if not o:
4811 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4811 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4812 return
4812 return
4813
4813
4814 revdag = cmdutil.graphrevs(repo, o, opts)
4814 revdag = cmdutil.graphrevs(repo, o, opts)
4815 displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
4815 displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
4816 cmdutil.displaygraph(ui, repo, revdag, displayer, graphmod.asciiedges)
4816 cmdutil.displaygraph(ui, repo, revdag, displayer, graphmod.asciiedges)
4817 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4817 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4818 return 0
4818 return 0
4819
4819
4820 if opts.get('bookmarks'):
4820 if opts.get('bookmarks'):
4821 dest = ui.expandpath(dest or 'default-push', dest or 'default')
4821 dest = ui.expandpath(dest or 'default-push', dest or 'default')
4822 dest, branches = hg.parseurl(dest, opts.get('branch'))
4822 dest, branches = hg.parseurl(dest, opts.get('branch'))
4823 other = hg.peer(repo, opts, dest)
4823 other = hg.peer(repo, opts, dest)
4824 if 'bookmarks' not in other.listkeys('namespaces'):
4824 if 'bookmarks' not in other.listkeys('namespaces'):
4825 ui.warn(_("remote doesn't support bookmarks\n"))
4825 ui.warn(_("remote doesn't support bookmarks\n"))
4826 return 0
4826 return 0
4827 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
4827 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
4828 return bookmarks.outgoing(ui, repo, other)
4828 return bookmarks.outgoing(ui, repo, other)
4829
4829
4830 repo._subtoppath = ui.expandpath(dest or 'default-push', dest or 'default')
4830 repo._subtoppath = ui.expandpath(dest or 'default-push', dest or 'default')
4831 try:
4831 try:
4832 return hg.outgoing(ui, repo, dest, opts)
4832 return hg.outgoing(ui, repo, dest, opts)
4833 finally:
4833 finally:
4834 del repo._subtoppath
4834 del repo._subtoppath
4835
4835
4836 @command('parents',
4836 @command('parents',
4837 [('r', 'rev', '', _('show parents of the specified revision'), _('REV')),
4837 [('r', 'rev', '', _('show parents of the specified revision'), _('REV')),
4838 ] + templateopts,
4838 ] + templateopts,
4839 _('[-r REV] [FILE]'),
4839 _('[-r REV] [FILE]'),
4840 inferrepo=True)
4840 inferrepo=True)
4841 def parents(ui, repo, file_=None, **opts):
4841 def parents(ui, repo, file_=None, **opts):
4842 """show the parents of the working directory or revision (DEPRECATED)
4842 """show the parents of the working directory or revision (DEPRECATED)
4843
4843
4844 Print the working directory's parent revisions. If a revision is
4844 Print the working directory's parent revisions. If a revision is
4845 given via -r/--rev, the parent of that revision will be printed.
4845 given via -r/--rev, the parent of that revision will be printed.
4846 If a file argument is given, the revision in which the file was
4846 If a file argument is given, the revision in which the file was
4847 last changed (before the working directory revision or the
4847 last changed (before the working directory revision or the
4848 argument to --rev if given) is printed.
4848 argument to --rev if given) is printed.
4849
4849
4850 This command is equivalent to::
4850 This command is equivalent to::
4851
4851
4852 hg log -r "p1()+p2()" or
4852 hg log -r "p1()+p2()" or
4853 hg log -r "p1(REV)+p2(REV)" or
4853 hg log -r "p1(REV)+p2(REV)" or
4854 hg log -r "max(::p1() and file(FILE))+max(::p2() and file(FILE))" or
4854 hg log -r "max(::p1() and file(FILE))+max(::p2() and file(FILE))" or
4855 hg log -r "max(::p1(REV) and file(FILE))+max(::p2(REV) and file(FILE))"
4855 hg log -r "max(::p1(REV) and file(FILE))+max(::p2(REV) and file(FILE))"
4856
4856
4857 See :hg:`summary` and :hg:`help revsets` for related information.
4857 See :hg:`summary` and :hg:`help revsets` for related information.
4858
4858
4859 Returns 0 on success.
4859 Returns 0 on success.
4860 """
4860 """
4861
4861
4862 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
4862 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
4863
4863
4864 if file_:
4864 if file_:
4865 m = scmutil.match(ctx, (file_,), opts)
4865 m = scmutil.match(ctx, (file_,), opts)
4866 if m.anypats() or len(m.files()) != 1:
4866 if m.anypats() or len(m.files()) != 1:
4867 raise error.Abort(_('can only specify an explicit filename'))
4867 raise error.Abort(_('can only specify an explicit filename'))
4868 file_ = m.files()[0]
4868 file_ = m.files()[0]
4869 filenodes = []
4869 filenodes = []
4870 for cp in ctx.parents():
4870 for cp in ctx.parents():
4871 if not cp:
4871 if not cp:
4872 continue
4872 continue
4873 try:
4873 try:
4874 filenodes.append(cp.filenode(file_))
4874 filenodes.append(cp.filenode(file_))
4875 except error.LookupError:
4875 except error.LookupError:
4876 pass
4876 pass
4877 if not filenodes:
4877 if not filenodes:
4878 raise error.Abort(_("'%s' not found in manifest!") % file_)
4878 raise error.Abort(_("'%s' not found in manifest!") % file_)
4879 p = []
4879 p = []
4880 for fn in filenodes:
4880 for fn in filenodes:
4881 fctx = repo.filectx(file_, fileid=fn)
4881 fctx = repo.filectx(file_, fileid=fn)
4882 p.append(fctx.node())
4882 p.append(fctx.node())
4883 else:
4883 else:
4884 p = [cp.node() for cp in ctx.parents()]
4884 p = [cp.node() for cp in ctx.parents()]
4885
4885
4886 displayer = cmdutil.show_changeset(ui, repo, opts)
4886 displayer = cmdutil.show_changeset(ui, repo, opts)
4887 for n in p:
4887 for n in p:
4888 if n != nullid:
4888 if n != nullid:
4889 displayer.show(repo[n])
4889 displayer.show(repo[n])
4890 displayer.close()
4890 displayer.close()
4891
4891
4892 @command('paths', formatteropts, _('[NAME]'), optionalrepo=True)
4892 @command('paths', formatteropts, _('[NAME]'), optionalrepo=True)
4893 def paths(ui, repo, search=None, **opts):
4893 def paths(ui, repo, search=None, **opts):
4894 """show aliases for remote repositories
4894 """show aliases for remote repositories
4895
4895
4896 Show definition of symbolic path name NAME. If no name is given,
4896 Show definition of symbolic path name NAME. If no name is given,
4897 show definition of all available names.
4897 show definition of all available names.
4898
4898
4899 Option -q/--quiet suppresses all output when searching for NAME
4899 Option -q/--quiet suppresses all output when searching for NAME
4900 and shows only the path names when listing all definitions.
4900 and shows only the path names when listing all definitions.
4901
4901
4902 Path names are defined in the [paths] section of your
4902 Path names are defined in the [paths] section of your
4903 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
4903 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
4904 repository, ``.hg/hgrc`` is used, too.
4904 repository, ``.hg/hgrc`` is used, too.
4905
4905
4906 The path names ``default`` and ``default-push`` have a special
4906 The path names ``default`` and ``default-push`` have a special
4907 meaning. When performing a push or pull operation, they are used
4907 meaning. When performing a push or pull operation, they are used
4908 as fallbacks if no location is specified on the command-line.
4908 as fallbacks if no location is specified on the command-line.
4909 When ``default-push`` is set, it will be used for push and
4909 When ``default-push`` is set, it will be used for push and
4910 ``default`` will be used for pull; otherwise ``default`` is used
4910 ``default`` will be used for pull; otherwise ``default`` is used
4911 as the fallback for both. When cloning a repository, the clone
4911 as the fallback for both. When cloning a repository, the clone
4912 source is written as ``default`` in ``.hg/hgrc``.
4912 source is written as ``default`` in ``.hg/hgrc``.
4913
4913
4914 .. note::
4914 .. note::
4915
4915
4916 ``default`` and ``default-push`` apply to all inbound (e.g.
4916 ``default`` and ``default-push`` apply to all inbound (e.g.
4917 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email`
4917 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email`
4918 and :hg:`bundle`) operations.
4918 and :hg:`bundle`) operations.
4919
4919
4920 See :hg:`help urls` for more information.
4920 See :hg:`help urls` for more information.
4921
4921
4922 Returns 0 on success.
4922 Returns 0 on success.
4923 """
4923 """
4924 if search:
4924 if search:
4925 pathitems = [(name, path) for name, path in ui.paths.iteritems()
4925 pathitems = [(name, path) for name, path in ui.paths.iteritems()
4926 if name == search]
4926 if name == search]
4927 else:
4927 else:
4928 pathitems = sorted(ui.paths.iteritems())
4928 pathitems = sorted(ui.paths.iteritems())
4929
4929
4930 fm = ui.formatter('paths', opts)
4930 fm = ui.formatter('paths', opts)
4931 if fm.isplain():
4931 if fm.isplain():
4932 hidepassword = util.hidepassword
4932 hidepassword = util.hidepassword
4933 else:
4933 else:
4934 hidepassword = str
4934 hidepassword = str
4935 if ui.quiet:
4935 if ui.quiet:
4936 namefmt = '%s\n'
4936 namefmt = '%s\n'
4937 else:
4937 else:
4938 namefmt = '%s = '
4938 namefmt = '%s = '
4939 showsubopts = not search and not ui.quiet
4939 showsubopts = not search and not ui.quiet
4940
4940
4941 for name, path in pathitems:
4941 for name, path in pathitems:
4942 fm.startitem()
4942 fm.startitem()
4943 fm.condwrite(not search, 'name', namefmt, name)
4943 fm.condwrite(not search, 'name', namefmt, name)
4944 fm.condwrite(not ui.quiet, 'url', '%s\n', hidepassword(path.rawloc))
4944 fm.condwrite(not ui.quiet, 'url', '%s\n', hidepassword(path.rawloc))
4945 for subopt, value in sorted(path.suboptions.items()):
4945 for subopt, value in sorted(path.suboptions.items()):
4946 assert subopt not in ('name', 'url')
4946 assert subopt not in ('name', 'url')
4947 if showsubopts:
4947 if showsubopts:
4948 fm.plain('%s:%s = ' % (name, subopt))
4948 fm.plain('%s:%s = ' % (name, subopt))
4949 fm.condwrite(showsubopts, subopt, '%s\n', value)
4949 fm.condwrite(showsubopts, subopt, '%s\n', value)
4950
4950
4951 fm.end()
4951 fm.end()
4952
4952
4953 if search and not pathitems:
4953 if search and not pathitems:
4954 if not ui.quiet:
4954 if not ui.quiet:
4955 ui.warn(_("not found!\n"))
4955 ui.warn(_("not found!\n"))
4956 return 1
4956 return 1
4957 else:
4957 else:
4958 return 0
4958 return 0
4959
4959
4960 @command('phase',
4960 @command('phase',
4961 [('p', 'public', False, _('set changeset phase to public')),
4961 [('p', 'public', False, _('set changeset phase to public')),
4962 ('d', 'draft', False, _('set changeset phase to draft')),
4962 ('d', 'draft', False, _('set changeset phase to draft')),
4963 ('s', 'secret', False, _('set changeset phase to secret')),
4963 ('s', 'secret', False, _('set changeset phase to secret')),
4964 ('f', 'force', False, _('allow to move boundary backward')),
4964 ('f', 'force', False, _('allow to move boundary backward')),
4965 ('r', 'rev', [], _('target revision'), _('REV')),
4965 ('r', 'rev', [], _('target revision'), _('REV')),
4966 ],
4966 ],
4967 _('[-p|-d|-s] [-f] [-r] [REV...]'))
4967 _('[-p|-d|-s] [-f] [-r] [REV...]'))
4968 def phase(ui, repo, *revs, **opts):
4968 def phase(ui, repo, *revs, **opts):
4969 """set or show the current phase name
4969 """set or show the current phase name
4970
4970
4971 With no argument, show the phase name of the current revision(s).
4971 With no argument, show the phase name of the current revision(s).
4972
4972
4973 With one of -p/--public, -d/--draft or -s/--secret, change the
4973 With one of -p/--public, -d/--draft or -s/--secret, change the
4974 phase value of the specified revisions.
4974 phase value of the specified revisions.
4975
4975
4976 Unless -f/--force is specified, :hg:`phase` won't move changeset from a
4976 Unless -f/--force is specified, :hg:`phase` won't move changeset from a
4977 lower phase to an higher phase. Phases are ordered as follows::
4977 lower phase to an higher phase. Phases are ordered as follows::
4978
4978
4979 public < draft < secret
4979 public < draft < secret
4980
4980
4981 Returns 0 on success, 1 if some phases could not be changed.
4981 Returns 0 on success, 1 if some phases could not be changed.
4982
4982
4983 (For more information about the phases concept, see :hg:`help phases`.)
4983 (For more information about the phases concept, see :hg:`help phases`.)
4984 """
4984 """
4985 # search for a unique phase argument
4985 # search for a unique phase argument
4986 targetphase = None
4986 targetphase = None
4987 for idx, name in enumerate(phases.phasenames):
4987 for idx, name in enumerate(phases.phasenames):
4988 if opts[name]:
4988 if opts[name]:
4989 if targetphase is not None:
4989 if targetphase is not None:
4990 raise error.Abort(_('only one phase can be specified'))
4990 raise error.Abort(_('only one phase can be specified'))
4991 targetphase = idx
4991 targetphase = idx
4992
4992
4993 # look for specified revision
4993 # look for specified revision
4994 revs = list(revs)
4994 revs = list(revs)
4995 revs.extend(opts['rev'])
4995 revs.extend(opts['rev'])
4996 if not revs:
4996 if not revs:
4997 # display both parents as the second parent phase can influence
4997 # display both parents as the second parent phase can influence
4998 # the phase of a merge commit
4998 # the phase of a merge commit
4999 revs = [c.rev() for c in repo[None].parents()]
4999 revs = [c.rev() for c in repo[None].parents()]
5000
5000
5001 revs = scmutil.revrange(repo, revs)
5001 revs = scmutil.revrange(repo, revs)
5002
5002
5003 lock = None
5003 lock = None
5004 ret = 0
5004 ret = 0
5005 if targetphase is None:
5005 if targetphase is None:
5006 # display
5006 # display
5007 for r in revs:
5007 for r in revs:
5008 ctx = repo[r]
5008 ctx = repo[r]
5009 ui.write('%i: %s\n' % (ctx.rev(), ctx.phasestr()))
5009 ui.write('%i: %s\n' % (ctx.rev(), ctx.phasestr()))
5010 else:
5010 else:
5011 tr = None
5011 tr = None
5012 lock = repo.lock()
5012 lock = repo.lock()
5013 try:
5013 try:
5014 tr = repo.transaction("phase")
5014 tr = repo.transaction("phase")
5015 # set phase
5015 # set phase
5016 if not revs:
5016 if not revs:
5017 raise error.Abort(_('empty revision set'))
5017 raise error.Abort(_('empty revision set'))
5018 nodes = [repo[r].node() for r in revs]
5018 nodes = [repo[r].node() for r in revs]
5019 # moving revision from public to draft may hide them
5019 # moving revision from public to draft may hide them
5020 # We have to check result on an unfiltered repository
5020 # We have to check result on an unfiltered repository
5021 unfi = repo.unfiltered()
5021 unfi = repo.unfiltered()
5022 getphase = unfi._phasecache.phase
5022 getphase = unfi._phasecache.phase
5023 olddata = [getphase(unfi, r) for r in unfi]
5023 olddata = [getphase(unfi, r) for r in unfi]
5024 phases.advanceboundary(repo, tr, targetphase, nodes)
5024 phases.advanceboundary(repo, tr, targetphase, nodes)
5025 if opts['force']:
5025 if opts['force']:
5026 phases.retractboundary(repo, tr, targetphase, nodes)
5026 phases.retractboundary(repo, tr, targetphase, nodes)
5027 tr.close()
5027 tr.close()
5028 finally:
5028 finally:
5029 if tr is not None:
5029 if tr is not None:
5030 tr.release()
5030 tr.release()
5031 lock.release()
5031 lock.release()
5032 getphase = unfi._phasecache.phase
5032 getphase = unfi._phasecache.phase
5033 newdata = [getphase(unfi, r) for r in unfi]
5033 newdata = [getphase(unfi, r) for r in unfi]
5034 changes = sum(newdata[r] != olddata[r] for r in unfi)
5034 changes = sum(newdata[r] != olddata[r] for r in unfi)
5035 cl = unfi.changelog
5035 cl = unfi.changelog
5036 rejected = [n for n in nodes
5036 rejected = [n for n in nodes
5037 if newdata[cl.rev(n)] < targetphase]
5037 if newdata[cl.rev(n)] < targetphase]
5038 if rejected:
5038 if rejected:
5039 ui.warn(_('cannot move %i changesets to a higher '
5039 ui.warn(_('cannot move %i changesets to a higher '
5040 'phase, use --force\n') % len(rejected))
5040 'phase, use --force\n') % len(rejected))
5041 ret = 1
5041 ret = 1
5042 if changes:
5042 if changes:
5043 msg = _('phase changed for %i changesets\n') % changes
5043 msg = _('phase changed for %i changesets\n') % changes
5044 if ret:
5044 if ret:
5045 ui.status(msg)
5045 ui.status(msg)
5046 else:
5046 else:
5047 ui.note(msg)
5047 ui.note(msg)
5048 else:
5048 else:
5049 ui.warn(_('no phases changed\n'))
5049 ui.warn(_('no phases changed\n'))
5050 return ret
5050 return ret
5051
5051
5052 def postincoming(ui, repo, modheads, optupdate, checkout, brev):
5052 def postincoming(ui, repo, modheads, optupdate, checkout, brev):
5053 """Run after a changegroup has been added via pull/unbundle
5053 """Run after a changegroup has been added via pull/unbundle
5054
5054
5055 This takes arguments below:
5055 This takes arguments below:
5056
5056
5057 :modheads: change of heads by pull/unbundle
5057 :modheads: change of heads by pull/unbundle
5058 :optupdate: updating working directory is needed or not
5058 :optupdate: updating working directory is needed or not
5059 :checkout: update destination revision (or None to default destination)
5059 :checkout: update destination revision (or None to default destination)
5060 :brev: a name, which might be a bookmark to be activated after updating
5060 :brev: a name, which might be a bookmark to be activated after updating
5061 """
5061 """
5062 if modheads == 0:
5062 if modheads == 0:
5063 return
5063 return
5064 if optupdate:
5064 if optupdate:
5065 try:
5065 try:
5066 return hg.updatetotally(ui, repo, checkout, brev)
5066 return hg.updatetotally(ui, repo, checkout, brev)
5067 except error.UpdateAbort as inst:
5067 except error.UpdateAbort as inst:
5068 msg = _("not updating: %s") % str(inst)
5068 msg = _("not updating: %s") % str(inst)
5069 hint = inst.hint
5069 hint = inst.hint
5070 raise error.UpdateAbort(msg, hint=hint)
5070 raise error.UpdateAbort(msg, hint=hint)
5071 if modheads > 1:
5071 if modheads > 1:
5072 currentbranchheads = len(repo.branchheads())
5072 currentbranchheads = len(repo.branchheads())
5073 if currentbranchheads == modheads:
5073 if currentbranchheads == modheads:
5074 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
5074 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
5075 elif currentbranchheads > 1:
5075 elif currentbranchheads > 1:
5076 ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to "
5076 ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to "
5077 "merge)\n"))
5077 "merge)\n"))
5078 else:
5078 else:
5079 ui.status(_("(run 'hg heads' to see heads)\n"))
5079 ui.status(_("(run 'hg heads' to see heads)\n"))
5080 else:
5080 else:
5081 ui.status(_("(run 'hg update' to get a working copy)\n"))
5081 ui.status(_("(run 'hg update' to get a working copy)\n"))
5082
5082
5083 @command('^pull',
5083 @command('^pull',
5084 [('u', 'update', None,
5084 [('u', 'update', None,
5085 _('update to new branch head if changesets were pulled')),
5085 _('update to new branch head if changesets were pulled')),
5086 ('f', 'force', None, _('run even when remote repository is unrelated')),
5086 ('f', 'force', None, _('run even when remote repository is unrelated')),
5087 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
5087 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
5088 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
5088 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
5089 ('b', 'branch', [], _('a specific branch you would like to pull'),
5089 ('b', 'branch', [], _('a specific branch you would like to pull'),
5090 _('BRANCH')),
5090 _('BRANCH')),
5091 ] + remoteopts,
5091 ] + remoteopts,
5092 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'))
5092 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'))
5093 def pull(ui, repo, source="default", **opts):
5093 def pull(ui, repo, source="default", **opts):
5094 """pull changes from the specified source
5094 """pull changes from the specified source
5095
5095
5096 Pull changes from a remote repository to a local one.
5096 Pull changes from a remote repository to a local one.
5097
5097
5098 This finds all changes from the repository at the specified path
5098 This finds all changes from the repository at the specified path
5099 or URL and adds them to a local repository (the current one unless
5099 or URL and adds them to a local repository (the current one unless
5100 -R is specified). By default, this does not update the copy of the
5100 -R is specified). By default, this does not update the copy of the
5101 project in the working directory.
5101 project in the working directory.
5102
5102
5103 Use :hg:`incoming` if you want to see what would have been added
5103 Use :hg:`incoming` if you want to see what would have been added
5104 by a pull at the time you issued this command. If you then decide
5104 by a pull at the time you issued this command. If you then decide
5105 to add those changes to the repository, you should use :hg:`pull
5105 to add those changes to the repository, you should use :hg:`pull
5106 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
5106 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
5107
5107
5108 If SOURCE is omitted, the 'default' path will be used.
5108 If SOURCE is omitted, the 'default' path will be used.
5109 See :hg:`help urls` for more information.
5109 See :hg:`help urls` for more information.
5110
5110
5111 Specifying bookmark as ``.`` is equivalent to specifying the active
5111 Specifying bookmark as ``.`` is equivalent to specifying the active
5112 bookmark's name.
5112 bookmark's name.
5113
5113
5114 Returns 0 on success, 1 if an update had unresolved files.
5114 Returns 0 on success, 1 if an update had unresolved files.
5115 """
5115 """
5116 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
5116 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
5117 ui.status(_('pulling from %s\n') % util.hidepassword(source))
5117 ui.status(_('pulling from %s\n') % util.hidepassword(source))
5118 other = hg.peer(repo, opts, source)
5118 other = hg.peer(repo, opts, source)
5119 try:
5119 try:
5120 revs, checkout = hg.addbranchrevs(repo, other, branches,
5120 revs, checkout = hg.addbranchrevs(repo, other, branches,
5121 opts.get('rev'))
5121 opts.get('rev'))
5122
5122
5123
5123
5124 pullopargs = {}
5124 pullopargs = {}
5125 if opts.get('bookmark'):
5125 if opts.get('bookmark'):
5126 if not revs:
5126 if not revs:
5127 revs = []
5127 revs = []
5128 # The list of bookmark used here is not the one used to actually
5128 # The list of bookmark used here is not the one used to actually
5129 # update the bookmark name. This can result in the revision pulled
5129 # update the bookmark name. This can result in the revision pulled
5130 # not ending up with the name of the bookmark because of a race
5130 # not ending up with the name of the bookmark because of a race
5131 # condition on the server. (See issue 4689 for details)
5131 # condition on the server. (See issue 4689 for details)
5132 remotebookmarks = other.listkeys('bookmarks')
5132 remotebookmarks = other.listkeys('bookmarks')
5133 pullopargs['remotebookmarks'] = remotebookmarks
5133 pullopargs['remotebookmarks'] = remotebookmarks
5134 for b in opts['bookmark']:
5134 for b in opts['bookmark']:
5135 b = repo._bookmarks.expandname(b)
5135 b = repo._bookmarks.expandname(b)
5136 if b not in remotebookmarks:
5136 if b not in remotebookmarks:
5137 raise error.Abort(_('remote bookmark %s not found!') % b)
5137 raise error.Abort(_('remote bookmark %s not found!') % b)
5138 revs.append(remotebookmarks[b])
5138 revs.append(remotebookmarks[b])
5139
5139
5140 if revs:
5140 if revs:
5141 try:
5141 try:
5142 # When 'rev' is a bookmark name, we cannot guarantee that it
5142 # When 'rev' is a bookmark name, we cannot guarantee that it
5143 # will be updated with that name because of a race condition
5143 # will be updated with that name because of a race condition
5144 # server side. (See issue 4689 for details)
5144 # server side. (See issue 4689 for details)
5145 oldrevs = revs
5145 oldrevs = revs
5146 revs = [] # actually, nodes
5146 revs = [] # actually, nodes
5147 for r in oldrevs:
5147 for r in oldrevs:
5148 node = other.lookup(r)
5148 node = other.lookup(r)
5149 revs.append(node)
5149 revs.append(node)
5150 if r == checkout:
5150 if r == checkout:
5151 checkout = node
5151 checkout = node
5152 except error.CapabilityError:
5152 except error.CapabilityError:
5153 err = _("other repository doesn't support revision lookup, "
5153 err = _("other repository doesn't support revision lookup, "
5154 "so a rev cannot be specified.")
5154 "so a rev cannot be specified.")
5155 raise error.Abort(err)
5155 raise error.Abort(err)
5156
5156
5157 pullopargs.update(opts.get('opargs', {}))
5157 pullopargs.update(opts.get('opargs', {}))
5158 modheads = exchange.pull(repo, other, heads=revs,
5158 modheads = exchange.pull(repo, other, heads=revs,
5159 force=opts.get('force'),
5159 force=opts.get('force'),
5160 bookmarks=opts.get('bookmark', ()),
5160 bookmarks=opts.get('bookmark', ()),
5161 opargs=pullopargs).cgresult
5161 opargs=pullopargs).cgresult
5162
5162
5163 # brev is a name, which might be a bookmark to be activated at
5163 # brev is a name, which might be a bookmark to be activated at
5164 # the end of the update. In other words, it is an explicit
5164 # the end of the update. In other words, it is an explicit
5165 # destination of the update
5165 # destination of the update
5166 brev = None
5166 brev = None
5167
5167
5168 if checkout:
5168 if checkout:
5169 checkout = str(repo.changelog.rev(checkout))
5169 checkout = str(repo.changelog.rev(checkout))
5170
5170
5171 # order below depends on implementation of
5171 # order below depends on implementation of
5172 # hg.addbranchrevs(). opts['bookmark'] is ignored,
5172 # hg.addbranchrevs(). opts['bookmark'] is ignored,
5173 # because 'checkout' is determined without it.
5173 # because 'checkout' is determined without it.
5174 if opts.get('rev'):
5174 if opts.get('rev'):
5175 brev = opts['rev'][0]
5175 brev = opts['rev'][0]
5176 elif opts.get('branch'):
5176 elif opts.get('branch'):
5177 brev = opts['branch'][0]
5177 brev = opts['branch'][0]
5178 else:
5178 else:
5179 brev = branches[0]
5179 brev = branches[0]
5180 repo._subtoppath = source
5180 repo._subtoppath = source
5181 try:
5181 try:
5182 ret = postincoming(ui, repo, modheads, opts.get('update'),
5182 ret = postincoming(ui, repo, modheads, opts.get('update'),
5183 checkout, brev)
5183 checkout, brev)
5184
5184
5185 finally:
5185 finally:
5186 del repo._subtoppath
5186 del repo._subtoppath
5187
5187
5188 finally:
5188 finally:
5189 other.close()
5189 other.close()
5190 return ret
5190 return ret
5191
5191
5192 @command('^push',
5192 @command('^push',
5193 [('f', 'force', None, _('force push')),
5193 [('f', 'force', None, _('force push')),
5194 ('r', 'rev', [],
5194 ('r', 'rev', [],
5195 _('a changeset intended to be included in the destination'),
5195 _('a changeset intended to be included in the destination'),
5196 _('REV')),
5196 _('REV')),
5197 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
5197 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
5198 ('b', 'branch', [],
5198 ('b', 'branch', [],
5199 _('a specific branch you would like to push'), _('BRANCH')),
5199 _('a specific branch you would like to push'), _('BRANCH')),
5200 ('', 'new-branch', False, _('allow pushing a new branch')),
5200 ('', 'new-branch', False, _('allow pushing a new branch')),
5201 ] + remoteopts,
5201 ] + remoteopts,
5202 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'))
5202 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'))
5203 def push(ui, repo, dest=None, **opts):
5203 def push(ui, repo, dest=None, **opts):
5204 """push changes to the specified destination
5204 """push changes to the specified destination
5205
5205
5206 Push changesets from the local repository to the specified
5206 Push changesets from the local repository to the specified
5207 destination.
5207 destination.
5208
5208
5209 This operation is symmetrical to pull: it is identical to a pull
5209 This operation is symmetrical to pull: it is identical to a pull
5210 in the destination repository from the current one.
5210 in the destination repository from the current one.
5211
5211
5212 By default, push will not allow creation of new heads at the
5212 By default, push will not allow creation of new heads at the
5213 destination, since multiple heads would make it unclear which head
5213 destination, since multiple heads would make it unclear which head
5214 to use. In this situation, it is recommended to pull and merge
5214 to use. In this situation, it is recommended to pull and merge
5215 before pushing.
5215 before pushing.
5216
5216
5217 Use --new-branch if you want to allow push to create a new named
5217 Use --new-branch if you want to allow push to create a new named
5218 branch that is not present at the destination. This allows you to
5218 branch that is not present at the destination. This allows you to
5219 only create a new branch without forcing other changes.
5219 only create a new branch without forcing other changes.
5220
5220
5221 .. note::
5221 .. note::
5222
5222
5223 Extra care should be taken with the -f/--force option,
5223 Extra care should be taken with the -f/--force option,
5224 which will push all new heads on all branches, an action which will
5224 which will push all new heads on all branches, an action which will
5225 almost always cause confusion for collaborators.
5225 almost always cause confusion for collaborators.
5226
5226
5227 If -r/--rev is used, the specified revision and all its ancestors
5227 If -r/--rev is used, the specified revision and all its ancestors
5228 will be pushed to the remote repository.
5228 will be pushed to the remote repository.
5229
5229
5230 If -B/--bookmark is used, the specified bookmarked revision, its
5230 If -B/--bookmark is used, the specified bookmarked revision, its
5231 ancestors, and the bookmark will be pushed to the remote
5231 ancestors, and the bookmark will be pushed to the remote
5232 repository. Specifying ``.`` is equivalent to specifying the active
5232 repository. Specifying ``.`` is equivalent to specifying the active
5233 bookmark's name.
5233 bookmark's name.
5234
5234
5235 Please see :hg:`help urls` for important details about ``ssh://``
5235 Please see :hg:`help urls` for important details about ``ssh://``
5236 URLs. If DESTINATION is omitted, a default path will be used.
5236 URLs. If DESTINATION is omitted, a default path will be used.
5237
5237
5238 Returns 0 if push was successful, 1 if nothing to push.
5238 Returns 0 if push was successful, 1 if nothing to push.
5239 """
5239 """
5240
5240
5241 if opts.get('bookmark'):
5241 if opts.get('bookmark'):
5242 ui.setconfig('bookmarks', 'pushing', opts['bookmark'], 'push')
5242 ui.setconfig('bookmarks', 'pushing', opts['bookmark'], 'push')
5243 for b in opts['bookmark']:
5243 for b in opts['bookmark']:
5244 # translate -B options to -r so changesets get pushed
5244 # translate -B options to -r so changesets get pushed
5245 b = repo._bookmarks.expandname(b)
5245 b = repo._bookmarks.expandname(b)
5246 if b in repo._bookmarks:
5246 if b in repo._bookmarks:
5247 opts.setdefault('rev', []).append(b)
5247 opts.setdefault('rev', []).append(b)
5248 else:
5248 else:
5249 # if we try to push a deleted bookmark, translate it to null
5249 # if we try to push a deleted bookmark, translate it to null
5250 # this lets simultaneous -r, -b options continue working
5250 # this lets simultaneous -r, -b options continue working
5251 opts.setdefault('rev', []).append("null")
5251 opts.setdefault('rev', []).append("null")
5252
5252
5253 path = ui.paths.getpath(dest, default=('default-push', 'default'))
5253 path = ui.paths.getpath(dest, default=('default-push', 'default'))
5254 if not path:
5254 if not path:
5255 raise error.Abort(_('default repository not configured!'),
5255 raise error.Abort(_('default repository not configured!'),
5256 hint=_("see 'hg help config.paths'"))
5256 hint=_("see 'hg help config.paths'"))
5257 dest = path.pushloc or path.loc
5257 dest = path.pushloc or path.loc
5258 branches = (path.branch, opts.get('branch') or [])
5258 branches = (path.branch, opts.get('branch') or [])
5259 ui.status(_('pushing to %s\n') % util.hidepassword(dest))
5259 ui.status(_('pushing to %s\n') % util.hidepassword(dest))
5260 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
5260 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
5261 other = hg.peer(repo, opts, dest)
5261 other = hg.peer(repo, opts, dest)
5262
5262
5263 if revs:
5263 if revs:
5264 revs = [repo.lookup(r) for r in scmutil.revrange(repo, revs)]
5264 revs = [repo.lookup(r) for r in scmutil.revrange(repo, revs)]
5265 if not revs:
5265 if not revs:
5266 raise error.Abort(_("specified revisions evaluate to an empty set"),
5266 raise error.Abort(_("specified revisions evaluate to an empty set"),
5267 hint=_("use different revision arguments"))
5267 hint=_("use different revision arguments"))
5268 elif path.pushrev:
5268 elif path.pushrev:
5269 # It doesn't make any sense to specify ancestor revisions. So limit
5269 # It doesn't make any sense to specify ancestor revisions. So limit
5270 # to DAG heads to make discovery simpler.
5270 # to DAG heads to make discovery simpler.
5271 expr = revset.formatspec('heads(%r)', path.pushrev)
5271 expr = revset.formatspec('heads(%r)', path.pushrev)
5272 revs = scmutil.revrange(repo, [expr])
5272 revs = scmutil.revrange(repo, [expr])
5273 revs = [repo[rev].node() for rev in revs]
5273 revs = [repo[rev].node() for rev in revs]
5274 if not revs:
5274 if not revs:
5275 raise error.Abort(_('default push revset for path evaluates to an '
5275 raise error.Abort(_('default push revset for path evaluates to an '
5276 'empty set'))
5276 'empty set'))
5277
5277
5278 repo._subtoppath = dest
5278 repo._subtoppath = dest
5279 try:
5279 try:
5280 # push subrepos depth-first for coherent ordering
5280 # push subrepos depth-first for coherent ordering
5281 c = repo['']
5281 c = repo['']
5282 subs = c.substate # only repos that are committed
5282 subs = c.substate # only repos that are committed
5283 for s in sorted(subs):
5283 for s in sorted(subs):
5284 result = c.sub(s).push(opts)
5284 result = c.sub(s).push(opts)
5285 if result == 0:
5285 if result == 0:
5286 return not result
5286 return not result
5287 finally:
5287 finally:
5288 del repo._subtoppath
5288 del repo._subtoppath
5289 pushop = exchange.push(repo, other, opts.get('force'), revs=revs,
5289 pushop = exchange.push(repo, other, opts.get('force'), revs=revs,
5290 newbranch=opts.get('new_branch'),
5290 newbranch=opts.get('new_branch'),
5291 bookmarks=opts.get('bookmark', ()),
5291 bookmarks=opts.get('bookmark', ()),
5292 opargs=opts.get('opargs'))
5292 opargs=opts.get('opargs'))
5293
5293
5294 result = not pushop.cgresult
5294 result = not pushop.cgresult
5295
5295
5296 if pushop.bkresult is not None:
5296 if pushop.bkresult is not None:
5297 if pushop.bkresult == 2:
5297 if pushop.bkresult == 2:
5298 result = 2
5298 result = 2
5299 elif not result and pushop.bkresult:
5299 elif not result and pushop.bkresult:
5300 result = 2
5300 result = 2
5301
5301
5302 return result
5302 return result
5303
5303
5304 @command('recover', [])
5304 @command('recover', [])
5305 def recover(ui, repo):
5305 def recover(ui, repo):
5306 """roll back an interrupted transaction
5306 """roll back an interrupted transaction
5307
5307
5308 Recover from an interrupted commit or pull.
5308 Recover from an interrupted commit or pull.
5309
5309
5310 This command tries to fix the repository status after an
5310 This command tries to fix the repository status after an
5311 interrupted operation. It should only be necessary when Mercurial
5311 interrupted operation. It should only be necessary when Mercurial
5312 suggests it.
5312 suggests it.
5313
5313
5314 Returns 0 if successful, 1 if nothing to recover or verify fails.
5314 Returns 0 if successful, 1 if nothing to recover or verify fails.
5315 """
5315 """
5316 if repo.recover():
5316 if repo.recover():
5317 return hg.verify(repo)
5317 return hg.verify(repo)
5318 return 1
5318 return 1
5319
5319
5320 @command('^remove|rm',
5320 @command('^remove|rm',
5321 [('A', 'after', None, _('record delete for missing files')),
5321 [('A', 'after', None, _('record delete for missing files')),
5322 ('f', 'force', None,
5322 ('f', 'force', None,
5323 _('forget added files, delete modified files')),
5323 _('forget added files, delete modified files')),
5324 ] + subrepoopts + walkopts,
5324 ] + subrepoopts + walkopts,
5325 _('[OPTION]... FILE...'),
5325 _('[OPTION]... FILE...'),
5326 inferrepo=True)
5326 inferrepo=True)
5327 def remove(ui, repo, *pats, **opts):
5327 def remove(ui, repo, *pats, **opts):
5328 """remove the specified files on the next commit
5328 """remove the specified files on the next commit
5329
5329
5330 Schedule the indicated files for removal from the current branch.
5330 Schedule the indicated files for removal from the current branch.
5331
5331
5332 This command schedules the files to be removed at the next commit.
5332 This command schedules the files to be removed at the next commit.
5333 To undo a remove before that, see :hg:`revert`. To undo added
5333 To undo a remove before that, see :hg:`revert`. To undo added
5334 files, see :hg:`forget`.
5334 files, see :hg:`forget`.
5335
5335
5336 .. container:: verbose
5336 .. container:: verbose
5337
5337
5338 -A/--after can be used to remove only files that have already
5338 -A/--after can be used to remove only files that have already
5339 been deleted, -f/--force can be used to force deletion, and -Af
5339 been deleted, -f/--force can be used to force deletion, and -Af
5340 can be used to remove files from the next revision without
5340 can be used to remove files from the next revision without
5341 deleting them from the working directory.
5341 deleting them from the working directory.
5342
5342
5343 The following table details the behavior of remove for different
5343 The following table details the behavior of remove for different
5344 file states (columns) and option combinations (rows). The file
5344 file states (columns) and option combinations (rows). The file
5345 states are Added [A], Clean [C], Modified [M] and Missing [!]
5345 states are Added [A], Clean [C], Modified [M] and Missing [!]
5346 (as reported by :hg:`status`). The actions are Warn, Remove
5346 (as reported by :hg:`status`). The actions are Warn, Remove
5347 (from branch) and Delete (from disk):
5347 (from branch) and Delete (from disk):
5348
5348
5349 ========= == == == ==
5349 ========= == == == ==
5350 opt/state A C M !
5350 opt/state A C M !
5351 ========= == == == ==
5351 ========= == == == ==
5352 none W RD W R
5352 none W RD W R
5353 -f R RD RD R
5353 -f R RD RD R
5354 -A W W W R
5354 -A W W W R
5355 -Af R R R R
5355 -Af R R R R
5356 ========= == == == ==
5356 ========= == == == ==
5357
5357
5358 .. note::
5358 .. note::
5359
5359
5360 :hg:`remove` never deletes files in Added [A] state from the
5360 :hg:`remove` never deletes files in Added [A] state from the
5361 working directory, not even if ``--force`` is specified.
5361 working directory, not even if ``--force`` is specified.
5362
5362
5363 Returns 0 on success, 1 if any warnings encountered.
5363 Returns 0 on success, 1 if any warnings encountered.
5364 """
5364 """
5365
5365
5366 after, force = opts.get('after'), opts.get('force')
5366 after, force = opts.get('after'), opts.get('force')
5367 if not pats and not after:
5367 if not pats and not after:
5368 raise error.Abort(_('no files specified'))
5368 raise error.Abort(_('no files specified'))
5369
5369
5370 m = scmutil.match(repo[None], pats, opts)
5370 m = scmutil.match(repo[None], pats, opts)
5371 subrepos = opts.get('subrepos')
5371 subrepos = opts.get('subrepos')
5372 return cmdutil.remove(ui, repo, m, "", after, force, subrepos)
5372 return cmdutil.remove(ui, repo, m, "", after, force, subrepos)
5373
5373
5374 @command('rename|move|mv',
5374 @command('rename|move|mv',
5375 [('A', 'after', None, _('record a rename that has already occurred')),
5375 [('A', 'after', None, _('record a rename that has already occurred')),
5376 ('f', 'force', None, _('forcibly copy over an existing managed file')),
5376 ('f', 'force', None, _('forcibly copy over an existing managed file')),
5377 ] + walkopts + dryrunopts,
5377 ] + walkopts + dryrunopts,
5378 _('[OPTION]... SOURCE... DEST'))
5378 _('[OPTION]... SOURCE... DEST'))
5379 def rename(ui, repo, *pats, **opts):
5379 def rename(ui, repo, *pats, **opts):
5380 """rename files; equivalent of copy + remove
5380 """rename files; equivalent of copy + remove
5381
5381
5382 Mark dest as copies of sources; mark sources for deletion. If dest
5382 Mark dest as copies of sources; mark sources for deletion. If dest
5383 is a directory, copies are put in that directory. If dest is a
5383 is a directory, copies are put in that directory. If dest is a
5384 file, there can only be one source.
5384 file, there can only be one source.
5385
5385
5386 By default, this command copies the contents of files as they
5386 By default, this command copies the contents of files as they
5387 exist in the working directory. If invoked with -A/--after, the
5387 exist in the working directory. If invoked with -A/--after, the
5388 operation is recorded, but no copying is performed.
5388 operation is recorded, but no copying is performed.
5389
5389
5390 This command takes effect at the next commit. To undo a rename
5390 This command takes effect at the next commit. To undo a rename
5391 before that, see :hg:`revert`.
5391 before that, see :hg:`revert`.
5392
5392
5393 Returns 0 on success, 1 if errors are encountered.
5393 Returns 0 on success, 1 if errors are encountered.
5394 """
5394 """
5395 with repo.wlock(False):
5395 with repo.wlock(False):
5396 return cmdutil.copy(ui, repo, pats, opts, rename=True)
5396 return cmdutil.copy(ui, repo, pats, opts, rename=True)
5397
5397
5398 @command('resolve',
5398 @command('resolve',
5399 [('a', 'all', None, _('select all unresolved files')),
5399 [('a', 'all', None, _('select all unresolved files')),
5400 ('l', 'list', None, _('list state of files needing merge')),
5400 ('l', 'list', None, _('list state of files needing merge')),
5401 ('m', 'mark', None, _('mark files as resolved')),
5401 ('m', 'mark', None, _('mark files as resolved')),
5402 ('u', 'unmark', None, _('mark files as unresolved')),
5402 ('u', 'unmark', None, _('mark files as unresolved')),
5403 ('n', 'no-status', None, _('hide status prefix'))]
5403 ('n', 'no-status', None, _('hide status prefix'))]
5404 + mergetoolopts + walkopts + formatteropts,
5404 + mergetoolopts + walkopts + formatteropts,
5405 _('[OPTION]... [FILE]...'),
5405 _('[OPTION]... [FILE]...'),
5406 inferrepo=True)
5406 inferrepo=True)
5407 def resolve(ui, repo, *pats, **opts):
5407 def resolve(ui, repo, *pats, **opts):
5408 """redo merges or set/view the merge status of files
5408 """redo merges or set/view the merge status of files
5409
5409
5410 Merges with unresolved conflicts are often the result of
5410 Merges with unresolved conflicts are often the result of
5411 non-interactive merging using the ``internal:merge`` configuration
5411 non-interactive merging using the ``internal:merge`` configuration
5412 setting, or a command-line merge tool like ``diff3``. The resolve
5412 setting, or a command-line merge tool like ``diff3``. The resolve
5413 command is used to manage the files involved in a merge, after
5413 command is used to manage the files involved in a merge, after
5414 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
5414 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
5415 working directory must have two parents). See :hg:`help
5415 working directory must have two parents). See :hg:`help
5416 merge-tools` for information on configuring merge tools.
5416 merge-tools` for information on configuring merge tools.
5417
5417
5418 The resolve command can be used in the following ways:
5418 The resolve command can be used in the following ways:
5419
5419
5420 - :hg:`resolve [--tool TOOL] FILE...`: attempt to re-merge the specified
5420 - :hg:`resolve [--tool TOOL] FILE...`: attempt to re-merge the specified
5421 files, discarding any previous merge attempts. Re-merging is not
5421 files, discarding any previous merge attempts. Re-merging is not
5422 performed for files already marked as resolved. Use ``--all/-a``
5422 performed for files already marked as resolved. Use ``--all/-a``
5423 to select all unresolved files. ``--tool`` can be used to specify
5423 to select all unresolved files. ``--tool`` can be used to specify
5424 the merge tool used for the given files. It overrides the HGMERGE
5424 the merge tool used for the given files. It overrides the HGMERGE
5425 environment variable and your configuration files. Previous file
5425 environment variable and your configuration files. Previous file
5426 contents are saved with a ``.orig`` suffix.
5426 contents are saved with a ``.orig`` suffix.
5427
5427
5428 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
5428 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
5429 (e.g. after having manually fixed-up the files). The default is
5429 (e.g. after having manually fixed-up the files). The default is
5430 to mark all unresolved files.
5430 to mark all unresolved files.
5431
5431
5432 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
5432 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
5433 default is to mark all resolved files.
5433 default is to mark all resolved files.
5434
5434
5435 - :hg:`resolve -l`: list files which had or still have conflicts.
5435 - :hg:`resolve -l`: list files which had or still have conflicts.
5436 In the printed list, ``U`` = unresolved and ``R`` = resolved.
5436 In the printed list, ``U`` = unresolved and ``R`` = resolved.
5437
5437
5438 .. note::
5438 .. note::
5439
5439
5440 Mercurial will not let you commit files with unresolved merge
5440 Mercurial will not let you commit files with unresolved merge
5441 conflicts. You must use :hg:`resolve -m ...` before you can
5441 conflicts. You must use :hg:`resolve -m ...` before you can
5442 commit after a conflicting merge.
5442 commit after a conflicting merge.
5443
5443
5444 Returns 0 on success, 1 if any files fail a resolve attempt.
5444 Returns 0 on success, 1 if any files fail a resolve attempt.
5445 """
5445 """
5446
5446
5447 flaglist = 'all mark unmark list no_status'.split()
5447 flaglist = 'all mark unmark list no_status'.split()
5448 all, mark, unmark, show, nostatus = \
5448 all, mark, unmark, show, nostatus = \
5449 [opts.get(o) for o in flaglist]
5449 [opts.get(o) for o in flaglist]
5450
5450
5451 if (show and (mark or unmark)) or (mark and unmark):
5451 if (show and (mark or unmark)) or (mark and unmark):
5452 raise error.Abort(_("too many options specified"))
5452 raise error.Abort(_("too many options specified"))
5453 if pats and all:
5453 if pats and all:
5454 raise error.Abort(_("can't specify --all and patterns"))
5454 raise error.Abort(_("can't specify --all and patterns"))
5455 if not (all or pats or show or mark or unmark):
5455 if not (all or pats or show or mark or unmark):
5456 raise error.Abort(_('no files or directories specified'),
5456 raise error.Abort(_('no files or directories specified'),
5457 hint=('use --all to re-merge all unresolved files'))
5457 hint=('use --all to re-merge all unresolved files'))
5458
5458
5459 if show:
5459 if show:
5460 fm = ui.formatter('resolve', opts)
5460 fm = ui.formatter('resolve', opts)
5461 ms = mergemod.mergestate.read(repo)
5461 ms = mergemod.mergestate.read(repo)
5462 m = scmutil.match(repo[None], pats, opts)
5462 m = scmutil.match(repo[None], pats, opts)
5463 for f in ms:
5463 for f in ms:
5464 if not m(f):
5464 if not m(f):
5465 continue
5465 continue
5466 l = 'resolve.' + {'u': 'unresolved', 'r': 'resolved',
5466 l = 'resolve.' + {'u': 'unresolved', 'r': 'resolved',
5467 'd': 'driverresolved'}[ms[f]]
5467 'd': 'driverresolved'}[ms[f]]
5468 fm.startitem()
5468 fm.startitem()
5469 fm.condwrite(not nostatus, 'status', '%s ', ms[f].upper(), label=l)
5469 fm.condwrite(not nostatus, 'status', '%s ', ms[f].upper(), label=l)
5470 fm.write('path', '%s\n', f, label=l)
5470 fm.write('path', '%s\n', f, label=l)
5471 fm.end()
5471 fm.end()
5472 return 0
5472 return 0
5473
5473
5474 with repo.wlock():
5474 with repo.wlock():
5475 ms = mergemod.mergestate.read(repo)
5475 ms = mergemod.mergestate.read(repo)
5476
5476
5477 if not (ms.active() or repo.dirstate.p2() != nullid):
5477 if not (ms.active() or repo.dirstate.p2() != nullid):
5478 raise error.Abort(
5478 raise error.Abort(
5479 _('resolve command not applicable when not merging'))
5479 _('resolve command not applicable when not merging'))
5480
5480
5481 wctx = repo[None]
5481 wctx = repo[None]
5482
5482
5483 if ms.mergedriver and ms.mdstate() == 'u':
5483 if ms.mergedriver and ms.mdstate() == 'u':
5484 proceed = mergemod.driverpreprocess(repo, ms, wctx)
5484 proceed = mergemod.driverpreprocess(repo, ms, wctx)
5485 ms.commit()
5485 ms.commit()
5486 # allow mark and unmark to go through
5486 # allow mark and unmark to go through
5487 if not mark and not unmark and not proceed:
5487 if not mark and not unmark and not proceed:
5488 return 1
5488 return 1
5489
5489
5490 m = scmutil.match(wctx, pats, opts)
5490 m = scmutil.match(wctx, pats, opts)
5491 ret = 0
5491 ret = 0
5492 didwork = False
5492 didwork = False
5493 runconclude = False
5493 runconclude = False
5494
5494
5495 tocomplete = []
5495 tocomplete = []
5496 for f in ms:
5496 for f in ms:
5497 if not m(f):
5497 if not m(f):
5498 continue
5498 continue
5499
5499
5500 didwork = True
5500 didwork = True
5501
5501
5502 # don't let driver-resolved files be marked, and run the conclude
5502 # don't let driver-resolved files be marked, and run the conclude
5503 # step if asked to resolve
5503 # step if asked to resolve
5504 if ms[f] == "d":
5504 if ms[f] == "d":
5505 exact = m.exact(f)
5505 exact = m.exact(f)
5506 if mark:
5506 if mark:
5507 if exact:
5507 if exact:
5508 ui.warn(_('not marking %s as it is driver-resolved\n')
5508 ui.warn(_('not marking %s as it is driver-resolved\n')
5509 % f)
5509 % f)
5510 elif unmark:
5510 elif unmark:
5511 if exact:
5511 if exact:
5512 ui.warn(_('not unmarking %s as it is driver-resolved\n')
5512 ui.warn(_('not unmarking %s as it is driver-resolved\n')
5513 % f)
5513 % f)
5514 else:
5514 else:
5515 runconclude = True
5515 runconclude = True
5516 continue
5516 continue
5517
5517
5518 if mark:
5518 if mark:
5519 ms.mark(f, "r")
5519 ms.mark(f, "r")
5520 elif unmark:
5520 elif unmark:
5521 ms.mark(f, "u")
5521 ms.mark(f, "u")
5522 else:
5522 else:
5523 # backup pre-resolve (merge uses .orig for its own purposes)
5523 # backup pre-resolve (merge uses .orig for its own purposes)
5524 a = repo.wjoin(f)
5524 a = repo.wjoin(f)
5525 try:
5525 try:
5526 util.copyfile(a, a + ".resolve")
5526 util.copyfile(a, a + ".resolve")
5527 except (IOError, OSError) as inst:
5527 except (IOError, OSError) as inst:
5528 if inst.errno != errno.ENOENT:
5528 if inst.errno != errno.ENOENT:
5529 raise
5529 raise
5530
5530
5531 try:
5531 try:
5532 # preresolve file
5532 # preresolve file
5533 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
5533 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
5534 'resolve')
5534 'resolve')
5535 complete, r = ms.preresolve(f, wctx)
5535 complete, r = ms.preresolve(f, wctx)
5536 if not complete:
5536 if not complete:
5537 tocomplete.append(f)
5537 tocomplete.append(f)
5538 elif r:
5538 elif r:
5539 ret = 1
5539 ret = 1
5540 finally:
5540 finally:
5541 ui.setconfig('ui', 'forcemerge', '', 'resolve')
5541 ui.setconfig('ui', 'forcemerge', '', 'resolve')
5542 ms.commit()
5542 ms.commit()
5543
5543
5544 # replace filemerge's .orig file with our resolve file, but only
5544 # replace filemerge's .orig file with our resolve file, but only
5545 # for merges that are complete
5545 # for merges that are complete
5546 if complete:
5546 if complete:
5547 try:
5547 try:
5548 util.rename(a + ".resolve",
5548 util.rename(a + ".resolve",
5549 scmutil.origpath(ui, repo, a))
5549 scmutil.origpath(ui, repo, a))
5550 except OSError as inst:
5550 except OSError as inst:
5551 if inst.errno != errno.ENOENT:
5551 if inst.errno != errno.ENOENT:
5552 raise
5552 raise
5553
5553
5554 for f in tocomplete:
5554 for f in tocomplete:
5555 try:
5555 try:
5556 # resolve file
5556 # resolve file
5557 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
5557 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
5558 'resolve')
5558 'resolve')
5559 r = ms.resolve(f, wctx)
5559 r = ms.resolve(f, wctx)
5560 if r:
5560 if r:
5561 ret = 1
5561 ret = 1
5562 finally:
5562 finally:
5563 ui.setconfig('ui', 'forcemerge', '', 'resolve')
5563 ui.setconfig('ui', 'forcemerge', '', 'resolve')
5564 ms.commit()
5564 ms.commit()
5565
5565
5566 # replace filemerge's .orig file with our resolve file
5566 # replace filemerge's .orig file with our resolve file
5567 a = repo.wjoin(f)
5567 a = repo.wjoin(f)
5568 try:
5568 try:
5569 util.rename(a + ".resolve", scmutil.origpath(ui, repo, a))
5569 util.rename(a + ".resolve", scmutil.origpath(ui, repo, a))
5570 except OSError as inst:
5570 except OSError as inst:
5571 if inst.errno != errno.ENOENT:
5571 if inst.errno != errno.ENOENT:
5572 raise
5572 raise
5573
5573
5574 ms.commit()
5574 ms.commit()
5575 ms.recordactions()
5575 ms.recordactions()
5576
5576
5577 if not didwork and pats:
5577 if not didwork and pats:
5578 hint = None
5578 hint = None
5579 if not any([p for p in pats if p.find(':') >= 0]):
5579 if not any([p for p in pats if p.find(':') >= 0]):
5580 pats = ['path:%s' % p for p in pats]
5580 pats = ['path:%s' % p for p in pats]
5581 m = scmutil.match(wctx, pats, opts)
5581 m = scmutil.match(wctx, pats, opts)
5582 for f in ms:
5582 for f in ms:
5583 if not m(f):
5583 if not m(f):
5584 continue
5584 continue
5585 flags = ''.join(['-%s ' % o[0] for o in flaglist
5585 flags = ''.join(['-%s ' % o[0] for o in flaglist
5586 if opts.get(o)])
5586 if opts.get(o)])
5587 hint = _("(try: hg resolve %s%s)\n") % (
5587 hint = _("(try: hg resolve %s%s)\n") % (
5588 flags,
5588 flags,
5589 ' '.join(pats))
5589 ' '.join(pats))
5590 break
5590 break
5591 ui.warn(_("arguments do not match paths that need resolving\n"))
5591 ui.warn(_("arguments do not match paths that need resolving\n"))
5592 if hint:
5592 if hint:
5593 ui.warn(hint)
5593 ui.warn(hint)
5594 elif ms.mergedriver and ms.mdstate() != 's':
5594 elif ms.mergedriver and ms.mdstate() != 's':
5595 # run conclude step when either a driver-resolved file is requested
5595 # run conclude step when either a driver-resolved file is requested
5596 # or there are no driver-resolved files
5596 # or there are no driver-resolved files
5597 # we can't use 'ret' to determine whether any files are unresolved
5597 # we can't use 'ret' to determine whether any files are unresolved
5598 # because we might not have tried to resolve some
5598 # because we might not have tried to resolve some
5599 if ((runconclude or not list(ms.driverresolved()))
5599 if ((runconclude or not list(ms.driverresolved()))
5600 and not list(ms.unresolved())):
5600 and not list(ms.unresolved())):
5601 proceed = mergemod.driverconclude(repo, ms, wctx)
5601 proceed = mergemod.driverconclude(repo, ms, wctx)
5602 ms.commit()
5602 ms.commit()
5603 if not proceed:
5603 if not proceed:
5604 return 1
5604 return 1
5605
5605
5606 # Nudge users into finishing an unfinished operation
5606 # Nudge users into finishing an unfinished operation
5607 unresolvedf = list(ms.unresolved())
5607 unresolvedf = list(ms.unresolved())
5608 driverresolvedf = list(ms.driverresolved())
5608 driverresolvedf = list(ms.driverresolved())
5609 if not unresolvedf and not driverresolvedf:
5609 if not unresolvedf and not driverresolvedf:
5610 ui.status(_('(no more unresolved files)\n'))
5610 ui.status(_('(no more unresolved files)\n'))
5611 cmdutil.checkafterresolved(repo)
5611 cmdutil.checkafterresolved(repo)
5612 elif not unresolvedf:
5612 elif not unresolvedf:
5613 ui.status(_('(no more unresolved files -- '
5613 ui.status(_('(no more unresolved files -- '
5614 'run "hg resolve --all" to conclude)\n'))
5614 'run "hg resolve --all" to conclude)\n'))
5615
5615
5616 return ret
5616 return ret
5617
5617
5618 @command('revert',
5618 @command('revert',
5619 [('a', 'all', None, _('revert all changes when no arguments given')),
5619 [('a', 'all', None, _('revert all changes when no arguments given')),
5620 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
5620 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
5621 ('r', 'rev', '', _('revert to the specified revision'), _('REV')),
5621 ('r', 'rev', '', _('revert to the specified revision'), _('REV')),
5622 ('C', 'no-backup', None, _('do not save backup copies of files')),
5622 ('C', 'no-backup', None, _('do not save backup copies of files')),
5623 ('i', 'interactive', None,
5623 ('i', 'interactive', None,
5624 _('interactively select the changes (EXPERIMENTAL)')),
5624 _('interactively select the changes (EXPERIMENTAL)')),
5625 ] + walkopts + dryrunopts,
5625 ] + walkopts + dryrunopts,
5626 _('[OPTION]... [-r REV] [NAME]...'))
5626 _('[OPTION]... [-r REV] [NAME]...'))
5627 def revert(ui, repo, *pats, **opts):
5627 def revert(ui, repo, *pats, **opts):
5628 """restore files to their checkout state
5628 """restore files to their checkout state
5629
5629
5630 .. note::
5630 .. note::
5631
5631
5632 To check out earlier revisions, you should use :hg:`update REV`.
5632 To check out earlier revisions, you should use :hg:`update REV`.
5633 To cancel an uncommitted merge (and lose your changes),
5633 To cancel an uncommitted merge (and lose your changes),
5634 use :hg:`update --clean .`.
5634 use :hg:`update --clean .`.
5635
5635
5636 With no revision specified, revert the specified files or directories
5636 With no revision specified, revert the specified files or directories
5637 to the contents they had in the parent of the working directory.
5637 to the contents they had in the parent of the working directory.
5638 This restores the contents of files to an unmodified
5638 This restores the contents of files to an unmodified
5639 state and unschedules adds, removes, copies, and renames. If the
5639 state and unschedules adds, removes, copies, and renames. If the
5640 working directory has two parents, you must explicitly specify a
5640 working directory has two parents, you must explicitly specify a
5641 revision.
5641 revision.
5642
5642
5643 Using the -r/--rev or -d/--date options, revert the given files or
5643 Using the -r/--rev or -d/--date options, revert the given files or
5644 directories to their states as of a specific revision. Because
5644 directories to their states as of a specific revision. Because
5645 revert does not change the working directory parents, this will
5645 revert does not change the working directory parents, this will
5646 cause these files to appear modified. This can be helpful to "back
5646 cause these files to appear modified. This can be helpful to "back
5647 out" some or all of an earlier change. See :hg:`backout` for a
5647 out" some or all of an earlier change. See :hg:`backout` for a
5648 related method.
5648 related method.
5649
5649
5650 Modified files are saved with a .orig suffix before reverting.
5650 Modified files are saved with a .orig suffix before reverting.
5651 To disable these backups, use --no-backup. It is possible to store
5651 To disable these backups, use --no-backup. It is possible to store
5652 the backup files in a custom directory relative to the root of the
5652 the backup files in a custom directory relative to the root of the
5653 repository by setting the ``ui.origbackuppath`` configuration
5653 repository by setting the ``ui.origbackuppath`` configuration
5654 option.
5654 option.
5655
5655
5656 See :hg:`help dates` for a list of formats valid for -d/--date.
5656 See :hg:`help dates` for a list of formats valid for -d/--date.
5657
5657
5658 See :hg:`help backout` for a way to reverse the effect of an
5658 See :hg:`help backout` for a way to reverse the effect of an
5659 earlier changeset.
5659 earlier changeset.
5660
5660
5661 Returns 0 on success.
5661 Returns 0 on success.
5662 """
5662 """
5663
5663
5664 if opts.get("date"):
5664 if opts.get("date"):
5665 if opts.get("rev"):
5665 if opts.get("rev"):
5666 raise error.Abort(_("you can't specify a revision and a date"))
5666 raise error.Abort(_("you can't specify a revision and a date"))
5667 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
5667 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
5668
5668
5669 parent, p2 = repo.dirstate.parents()
5669 parent, p2 = repo.dirstate.parents()
5670 if not opts.get('rev') and p2 != nullid:
5670 if not opts.get('rev') and p2 != nullid:
5671 # revert after merge is a trap for new users (issue2915)
5671 # revert after merge is a trap for new users (issue2915)
5672 raise error.Abort(_('uncommitted merge with no revision specified'),
5672 raise error.Abort(_('uncommitted merge with no revision specified'),
5673 hint=_("use 'hg update' or see 'hg help revert'"))
5673 hint=_("use 'hg update' or see 'hg help revert'"))
5674
5674
5675 ctx = scmutil.revsingle(repo, opts.get('rev'))
5675 ctx = scmutil.revsingle(repo, opts.get('rev'))
5676
5676
5677 if (not (pats or opts.get('include') or opts.get('exclude') or
5677 if (not (pats or opts.get('include') or opts.get('exclude') or
5678 opts.get('all') or opts.get('interactive'))):
5678 opts.get('all') or opts.get('interactive'))):
5679 msg = _("no files or directories specified")
5679 msg = _("no files or directories specified")
5680 if p2 != nullid:
5680 if p2 != nullid:
5681 hint = _("uncommitted merge, use --all to discard all changes,"
5681 hint = _("uncommitted merge, use --all to discard all changes,"
5682 " or 'hg update -C .' to abort the merge")
5682 " or 'hg update -C .' to abort the merge")
5683 raise error.Abort(msg, hint=hint)
5683 raise error.Abort(msg, hint=hint)
5684 dirty = any(repo.status())
5684 dirty = any(repo.status())
5685 node = ctx.node()
5685 node = ctx.node()
5686 if node != parent:
5686 if node != parent:
5687 if dirty:
5687 if dirty:
5688 hint = _("uncommitted changes, use --all to discard all"
5688 hint = _("uncommitted changes, use --all to discard all"
5689 " changes, or 'hg update %s' to update") % ctx.rev()
5689 " changes, or 'hg update %s' to update") % ctx.rev()
5690 else:
5690 else:
5691 hint = _("use --all to revert all files,"
5691 hint = _("use --all to revert all files,"
5692 " or 'hg update %s' to update") % ctx.rev()
5692 " or 'hg update %s' to update") % ctx.rev()
5693 elif dirty:
5693 elif dirty:
5694 hint = _("uncommitted changes, use --all to discard all changes")
5694 hint = _("uncommitted changes, use --all to discard all changes")
5695 else:
5695 else:
5696 hint = _("use --all to revert all files")
5696 hint = _("use --all to revert all files")
5697 raise error.Abort(msg, hint=hint)
5697 raise error.Abort(msg, hint=hint)
5698
5698
5699 return cmdutil.revert(ui, repo, ctx, (parent, p2), *pats, **opts)
5699 return cmdutil.revert(ui, repo, ctx, (parent, p2), *pats, **opts)
5700
5700
5701 @command('rollback', dryrunopts +
5701 @command('rollback', dryrunopts +
5702 [('f', 'force', False, _('ignore safety measures'))])
5702 [('f', 'force', False, _('ignore safety measures'))])
5703 def rollback(ui, repo, **opts):
5703 def rollback(ui, repo, **opts):
5704 """roll back the last transaction (DANGEROUS) (DEPRECATED)
5704 """roll back the last transaction (DANGEROUS) (DEPRECATED)
5705
5705
5706 Please use :hg:`commit --amend` instead of rollback to correct
5706 Please use :hg:`commit --amend` instead of rollback to correct
5707 mistakes in the last commit.
5707 mistakes in the last commit.
5708
5708
5709 This command should be used with care. There is only one level of
5709 This command should be used with care. There is only one level of
5710 rollback, and there is no way to undo a rollback. It will also
5710 rollback, and there is no way to undo a rollback. It will also
5711 restore the dirstate at the time of the last transaction, losing
5711 restore the dirstate at the time of the last transaction, losing
5712 any dirstate changes since that time. This command does not alter
5712 any dirstate changes since that time. This command does not alter
5713 the working directory.
5713 the working directory.
5714
5714
5715 Transactions are used to encapsulate the effects of all commands
5715 Transactions are used to encapsulate the effects of all commands
5716 that create new changesets or propagate existing changesets into a
5716 that create new changesets or propagate existing changesets into a
5717 repository.
5717 repository.
5718
5718
5719 .. container:: verbose
5719 .. container:: verbose
5720
5720
5721 For example, the following commands are transactional, and their
5721 For example, the following commands are transactional, and their
5722 effects can be rolled back:
5722 effects can be rolled back:
5723
5723
5724 - commit
5724 - commit
5725 - import
5725 - import
5726 - pull
5726 - pull
5727 - push (with this repository as the destination)
5727 - push (with this repository as the destination)
5728 - unbundle
5728 - unbundle
5729
5729
5730 To avoid permanent data loss, rollback will refuse to rollback a
5730 To avoid permanent data loss, rollback will refuse to rollback a
5731 commit transaction if it isn't checked out. Use --force to
5731 commit transaction if it isn't checked out. Use --force to
5732 override this protection.
5732 override this protection.
5733
5733
5734 The rollback command can be entirely disabled by setting the
5734 The rollback command can be entirely disabled by setting the
5735 ``ui.rollback`` configuration setting to false. If you're here
5735 ``ui.rollback`` configuration setting to false. If you're here
5736 because you want to use rollback and it's disabled, you can
5736 because you want to use rollback and it's disabled, you can
5737 re-enable the command by setting ``ui.rollback`` to true.
5737 re-enable the command by setting ``ui.rollback`` to true.
5738
5738
5739 This command is not intended for use on public repositories. Once
5739 This command is not intended for use on public repositories. Once
5740 changes are visible for pull by other users, rolling a transaction
5740 changes are visible for pull by other users, rolling a transaction
5741 back locally is ineffective (someone else may already have pulled
5741 back locally is ineffective (someone else may already have pulled
5742 the changes). Furthermore, a race is possible with readers of the
5742 the changes). Furthermore, a race is possible with readers of the
5743 repository; for example an in-progress pull from the repository
5743 repository; for example an in-progress pull from the repository
5744 may fail if a rollback is performed.
5744 may fail if a rollback is performed.
5745
5745
5746 Returns 0 on success, 1 if no rollback data is available.
5746 Returns 0 on success, 1 if no rollback data is available.
5747 """
5747 """
5748 if not ui.configbool('ui', 'rollback', True):
5748 if not ui.configbool('ui', 'rollback', True):
5749 raise error.Abort(_('rollback is disabled because it is unsafe'),
5749 raise error.Abort(_('rollback is disabled because it is unsafe'),
5750 hint=('see `hg help -v rollback` for information'))
5750 hint=('see `hg help -v rollback` for information'))
5751 return repo.rollback(dryrun=opts.get('dry_run'),
5751 return repo.rollback(dryrun=opts.get('dry_run'),
5752 force=opts.get('force'))
5752 force=opts.get('force'))
5753
5753
5754 @command('root', [])
5754 @command('root', [])
5755 def root(ui, repo):
5755 def root(ui, repo):
5756 """print the root (top) of the current working directory
5756 """print the root (top) of the current working directory
5757
5757
5758 Print the root directory of the current repository.
5758 Print the root directory of the current repository.
5759
5759
5760 Returns 0 on success.
5760 Returns 0 on success.
5761 """
5761 """
5762 ui.write(repo.root + "\n")
5762 ui.write(repo.root + "\n")
5763
5763
5764 @command('^serve',
5764 @command('^serve',
5765 [('A', 'accesslog', '', _('name of access log file to write to'),
5765 [('A', 'accesslog', '', _('name of access log file to write to'),
5766 _('FILE')),
5766 _('FILE')),
5767 ('d', 'daemon', None, _('run server in background')),
5767 ('d', 'daemon', None, _('run server in background')),
5768 ('', 'daemon-postexec', [], _('used internally by daemon mode')),
5768 ('', 'daemon-postexec', [], _('used internally by daemon mode')),
5769 ('E', 'errorlog', '', _('name of error log file to write to'), _('FILE')),
5769 ('E', 'errorlog', '', _('name of error log file to write to'), _('FILE')),
5770 # use string type, then we can check if something was passed
5770 # use string type, then we can check if something was passed
5771 ('p', 'port', '', _('port to listen on (default: 8000)'), _('PORT')),
5771 ('p', 'port', '', _('port to listen on (default: 8000)'), _('PORT')),
5772 ('a', 'address', '', _('address to listen on (default: all interfaces)'),
5772 ('a', 'address', '', _('address to listen on (default: all interfaces)'),
5773 _('ADDR')),
5773 _('ADDR')),
5774 ('', 'prefix', '', _('prefix path to serve from (default: server root)'),
5774 ('', 'prefix', '', _('prefix path to serve from (default: server root)'),
5775 _('PREFIX')),
5775 _('PREFIX')),
5776 ('n', 'name', '',
5776 ('n', 'name', '',
5777 _('name to show in web pages (default: working directory)'), _('NAME')),
5777 _('name to show in web pages (default: working directory)'), _('NAME')),
5778 ('', 'web-conf', '',
5778 ('', 'web-conf', '',
5779 _("name of the hgweb config file (see 'hg help hgweb')"), _('FILE')),
5779 _("name of the hgweb config file (see 'hg help hgweb')"), _('FILE')),
5780 ('', 'webdir-conf', '', _('name of the hgweb config file (DEPRECATED)'),
5780 ('', 'webdir-conf', '', _('name of the hgweb config file (DEPRECATED)'),
5781 _('FILE')),
5781 _('FILE')),
5782 ('', 'pid-file', '', _('name of file to write process ID to'), _('FILE')),
5782 ('', 'pid-file', '', _('name of file to write process ID to'), _('FILE')),
5783 ('', 'stdio', None, _('for remote clients')),
5783 ('', 'stdio', None, _('for remote clients')),
5784 ('', 'cmdserver', '', _('for remote clients'), _('MODE')),
5784 ('', 'cmdserver', '', _('for remote clients'), _('MODE')),
5785 ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')),
5785 ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')),
5786 ('', 'style', '', _('template style to use'), _('STYLE')),
5786 ('', 'style', '', _('template style to use'), _('STYLE')),
5787 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
5787 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
5788 ('', 'certificate', '', _('SSL certificate file'), _('FILE'))],
5788 ('', 'certificate', '', _('SSL certificate file'), _('FILE'))],
5789 _('[OPTION]...'),
5789 _('[OPTION]...'),
5790 optionalrepo=True)
5790 optionalrepo=True)
5791 def serve(ui, repo, **opts):
5791 def serve(ui, repo, **opts):
5792 """start stand-alone webserver
5792 """start stand-alone webserver
5793
5793
5794 Start a local HTTP repository browser and pull server. You can use
5794 Start a local HTTP repository browser and pull server. You can use
5795 this for ad-hoc sharing and browsing of repositories. It is
5795 this for ad-hoc sharing and browsing of repositories. It is
5796 recommended to use a real web server to serve a repository for
5796 recommended to use a real web server to serve a repository for
5797 longer periods of time.
5797 longer periods of time.
5798
5798
5799 Please note that the server does not implement access control.
5799 Please note that the server does not implement access control.
5800 This means that, by default, anybody can read from the server and
5800 This means that, by default, anybody can read from the server and
5801 nobody can write to it by default. Set the ``web.allow_push``
5801 nobody can write to it by default. Set the ``web.allow_push``
5802 option to ``*`` to allow everybody to push to the server. You
5802 option to ``*`` to allow everybody to push to the server. You
5803 should use a real web server if you need to authenticate users.
5803 should use a real web server if you need to authenticate users.
5804
5804
5805 By default, the server logs accesses to stdout and errors to
5805 By default, the server logs accesses to stdout and errors to
5806 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
5806 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
5807 files.
5807 files.
5808
5808
5809 To have the server choose a free port number to listen on, specify
5809 To have the server choose a free port number to listen on, specify
5810 a port number of 0; in this case, the server will print the port
5810 a port number of 0; in this case, the server will print the port
5811 number it uses.
5811 number it uses.
5812
5812
5813 Returns 0 on success.
5813 Returns 0 on success.
5814 """
5814 """
5815
5815
5816 if opts["stdio"] and opts["cmdserver"]:
5816 if opts["stdio"] and opts["cmdserver"]:
5817 raise error.Abort(_("cannot use --stdio with --cmdserver"))
5817 raise error.Abort(_("cannot use --stdio with --cmdserver"))
5818
5818
5819 if opts["stdio"]:
5819 if opts["stdio"]:
5820 if repo is None:
5820 if repo is None:
5821 raise error.RepoError(_("there is no Mercurial repository here"
5821 raise error.RepoError(_("there is no Mercurial repository here"
5822 " (.hg not found)"))
5822 " (.hg not found)"))
5823 s = sshserver.sshserver(ui, repo)
5823 s = sshserver.sshserver(ui, repo)
5824 s.serve_forever()
5824 s.serve_forever()
5825
5825
5826 service = server.createservice(ui, repo, opts)
5826 service = server.createservice(ui, repo, opts)
5827 return server.runservice(opts, initfn=service.init, runfn=service.run)
5827 return server.runservice(opts, initfn=service.init, runfn=service.run)
5828
5828
5829 @command('^status|st',
5829 @command('^status|st',
5830 [('A', 'all', None, _('show status of all files')),
5830 [('A', 'all', None, _('show status of all files')),
5831 ('m', 'modified', None, _('show only modified files')),
5831 ('m', 'modified', None, _('show only modified files')),
5832 ('a', 'added', None, _('show only added files')),
5832 ('a', 'added', None, _('show only added files')),
5833 ('r', 'removed', None, _('show only removed files')),
5833 ('r', 'removed', None, _('show only removed files')),
5834 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
5834 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
5835 ('c', 'clean', None, _('show only files without changes')),
5835 ('c', 'clean', None, _('show only files without changes')),
5836 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
5836 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
5837 ('i', 'ignored', None, _('show only ignored files')),
5837 ('i', 'ignored', None, _('show only ignored files')),
5838 ('n', 'no-status', None, _('hide status prefix')),
5838 ('n', 'no-status', None, _('hide status prefix')),
5839 ('C', 'copies', None, _('show source of copied files')),
5839 ('C', 'copies', None, _('show source of copied files')),
5840 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
5840 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
5841 ('', 'rev', [], _('show difference from revision'), _('REV')),
5841 ('', 'rev', [], _('show difference from revision'), _('REV')),
5842 ('', 'change', '', _('list the changed files of a revision'), _('REV')),
5842 ('', 'change', '', _('list the changed files of a revision'), _('REV')),
5843 ] + walkopts + subrepoopts + formatteropts,
5843 ] + walkopts + subrepoopts + formatteropts,
5844 _('[OPTION]... [FILE]...'),
5844 _('[OPTION]... [FILE]...'),
5845 inferrepo=True)
5845 inferrepo=True)
5846 def status(ui, repo, *pats, **opts):
5846 def status(ui, repo, *pats, **opts):
5847 """show changed files in the working directory
5847 """show changed files in the working directory
5848
5848
5849 Show status of files in the repository. If names are given, only
5849 Show status of files in the repository. If names are given, only
5850 files that match are shown. Files that are clean or ignored or
5850 files that match are shown. Files that are clean or ignored or
5851 the source of a copy/move operation, are not listed unless
5851 the source of a copy/move operation, are not listed unless
5852 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
5852 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
5853 Unless options described with "show only ..." are given, the
5853 Unless options described with "show only ..." are given, the
5854 options -mardu are used.
5854 options -mardu are used.
5855
5855
5856 Option -q/--quiet hides untracked (unknown and ignored) files
5856 Option -q/--quiet hides untracked (unknown and ignored) files
5857 unless explicitly requested with -u/--unknown or -i/--ignored.
5857 unless explicitly requested with -u/--unknown or -i/--ignored.
5858
5858
5859 .. note::
5859 .. note::
5860
5860
5861 :hg:`status` may appear to disagree with diff if permissions have
5861 :hg:`status` may appear to disagree with diff if permissions have
5862 changed or a merge has occurred. The standard diff format does
5862 changed or a merge has occurred. The standard diff format does
5863 not report permission changes and diff only reports changes
5863 not report permission changes and diff only reports changes
5864 relative to one merge parent.
5864 relative to one merge parent.
5865
5865
5866 If one revision is given, it is used as the base revision.
5866 If one revision is given, it is used as the base revision.
5867 If two revisions are given, the differences between them are
5867 If two revisions are given, the differences between them are
5868 shown. The --change option can also be used as a shortcut to list
5868 shown. The --change option can also be used as a shortcut to list
5869 the changed files of a revision from its first parent.
5869 the changed files of a revision from its first parent.
5870
5870
5871 The codes used to show the status of files are::
5871 The codes used to show the status of files are::
5872
5872
5873 M = modified
5873 M = modified
5874 A = added
5874 A = added
5875 R = removed
5875 R = removed
5876 C = clean
5876 C = clean
5877 ! = missing (deleted by non-hg command, but still tracked)
5877 ! = missing (deleted by non-hg command, but still tracked)
5878 ? = not tracked
5878 ? = not tracked
5879 I = ignored
5879 I = ignored
5880 = origin of the previous file (with --copies)
5880 = origin of the previous file (with --copies)
5881
5881
5882 .. container:: verbose
5882 .. container:: verbose
5883
5883
5884 Examples:
5884 Examples:
5885
5885
5886 - show changes in the working directory relative to a
5886 - show changes in the working directory relative to a
5887 changeset::
5887 changeset::
5888
5888
5889 hg status --rev 9353
5889 hg status --rev 9353
5890
5890
5891 - show changes in the working directory relative to the
5891 - show changes in the working directory relative to the
5892 current directory (see :hg:`help patterns` for more information)::
5892 current directory (see :hg:`help patterns` for more information)::
5893
5893
5894 hg status re:
5894 hg status re:
5895
5895
5896 - show all changes including copies in an existing changeset::
5896 - show all changes including copies in an existing changeset::
5897
5897
5898 hg status --copies --change 9353
5898 hg status --copies --change 9353
5899
5899
5900 - get a NUL separated list of added files, suitable for xargs::
5900 - get a NUL separated list of added files, suitable for xargs::
5901
5901
5902 hg status -an0
5902 hg status -an0
5903
5903
5904 Returns 0 on success.
5904 Returns 0 on success.
5905 """
5905 """
5906
5906
5907 revs = opts.get('rev')
5907 revs = opts.get('rev')
5908 change = opts.get('change')
5908 change = opts.get('change')
5909
5909
5910 if revs and change:
5910 if revs and change:
5911 msg = _('cannot specify --rev and --change at the same time')
5911 msg = _('cannot specify --rev and --change at the same time')
5912 raise error.Abort(msg)
5912 raise error.Abort(msg)
5913 elif change:
5913 elif change:
5914 node2 = scmutil.revsingle(repo, change, None).node()
5914 node2 = scmutil.revsingle(repo, change, None).node()
5915 node1 = repo[node2].p1().node()
5915 node1 = repo[node2].p1().node()
5916 else:
5916 else:
5917 node1, node2 = scmutil.revpair(repo, revs)
5917 node1, node2 = scmutil.revpair(repo, revs)
5918
5918
5919 if pats:
5919 if pats:
5920 cwd = repo.getcwd()
5920 cwd = repo.getcwd()
5921 else:
5921 else:
5922 cwd = ''
5922 cwd = ''
5923
5923
5924 if opts.get('print0'):
5924 if opts.get('print0'):
5925 end = '\0'
5925 end = '\0'
5926 else:
5926 else:
5927 end = '\n'
5927 end = '\n'
5928 copy = {}
5928 copy = {}
5929 states = 'modified added removed deleted unknown ignored clean'.split()
5929 states = 'modified added removed deleted unknown ignored clean'.split()
5930 show = [k for k in states if opts.get(k)]
5930 show = [k for k in states if opts.get(k)]
5931 if opts.get('all'):
5931 if opts.get('all'):
5932 show += ui.quiet and (states[:4] + ['clean']) or states
5932 show += ui.quiet and (states[:4] + ['clean']) or states
5933 if not show:
5933 if not show:
5934 if ui.quiet:
5934 if ui.quiet:
5935 show = states[:4]
5935 show = states[:4]
5936 else:
5936 else:
5937 show = states[:5]
5937 show = states[:5]
5938
5938
5939 m = scmutil.match(repo[node2], pats, opts)
5939 m = scmutil.match(repo[node2], pats, opts)
5940 stat = repo.status(node1, node2, m,
5940 stat = repo.status(node1, node2, m,
5941 'ignored' in show, 'clean' in show, 'unknown' in show,
5941 'ignored' in show, 'clean' in show, 'unknown' in show,
5942 opts.get('subrepos'))
5942 opts.get('subrepos'))
5943 changestates = zip(states, 'MAR!?IC', stat)
5943 changestates = zip(states, 'MAR!?IC', stat)
5944
5944
5945 if (opts.get('all') or opts.get('copies')
5945 if (opts.get('all') or opts.get('copies')
5946 or ui.configbool('ui', 'statuscopies')) and not opts.get('no_status'):
5946 or ui.configbool('ui', 'statuscopies')) and not opts.get('no_status'):
5947 copy = copies.pathcopies(repo[node1], repo[node2], m)
5947 copy = copies.pathcopies(repo[node1], repo[node2], m)
5948
5948
5949 fm = ui.formatter('status', opts)
5949 fm = ui.formatter('status', opts)
5950 fmt = '%s' + end
5950 fmt = '%s' + end
5951 showchar = not opts.get('no_status')
5951 showchar = not opts.get('no_status')
5952
5952
5953 for state, char, files in changestates:
5953 for state, char, files in changestates:
5954 if state in show:
5954 if state in show:
5955 label = 'status.' + state
5955 label = 'status.' + state
5956 for f in files:
5956 for f in files:
5957 fm.startitem()
5957 fm.startitem()
5958 fm.condwrite(showchar, 'status', '%s ', char, label=label)
5958 fm.condwrite(showchar, 'status', '%s ', char, label=label)
5959 fm.write('path', fmt, repo.pathto(f, cwd), label=label)
5959 fm.write('path', fmt, repo.pathto(f, cwd), label=label)
5960 if f in copy:
5960 if f in copy:
5961 fm.write("copy", ' %s' + end, repo.pathto(copy[f], cwd),
5961 fm.write("copy", ' %s' + end, repo.pathto(copy[f], cwd),
5962 label='status.copied')
5962 label='status.copied')
5963 fm.end()
5963 fm.end()
5964
5964
5965 @command('^summary|sum',
5965 @command('^summary|sum',
5966 [('', 'remote', None, _('check for push and pull'))], '[--remote]')
5966 [('', 'remote', None, _('check for push and pull'))], '[--remote]')
5967 def summary(ui, repo, **opts):
5967 def summary(ui, repo, **opts):
5968 """summarize working directory state
5968 """summarize working directory state
5969
5969
5970 This generates a brief summary of the working directory state,
5970 This generates a brief summary of the working directory state,
5971 including parents, branch, commit status, phase and available updates.
5971 including parents, branch, commit status, phase and available updates.
5972
5972
5973 With the --remote option, this will check the default paths for
5973 With the --remote option, this will check the default paths for
5974 incoming and outgoing changes. This can be time-consuming.
5974 incoming and outgoing changes. This can be time-consuming.
5975
5975
5976 Returns 0 on success.
5976 Returns 0 on success.
5977 """
5977 """
5978
5978
5979 ctx = repo[None]
5979 ctx = repo[None]
5980 parents = ctx.parents()
5980 parents = ctx.parents()
5981 pnode = parents[0].node()
5981 pnode = parents[0].node()
5982 marks = []
5982 marks = []
5983
5983
5984 ms = None
5984 ms = None
5985 try:
5985 try:
5986 ms = mergemod.mergestate.read(repo)
5986 ms = mergemod.mergestate.read(repo)
5987 except error.UnsupportedMergeRecords as e:
5987 except error.UnsupportedMergeRecords as e:
5988 s = ' '.join(e.recordtypes)
5988 s = ' '.join(e.recordtypes)
5989 ui.warn(
5989 ui.warn(
5990 _('warning: merge state has unsupported record types: %s\n') % s)
5990 _('warning: merge state has unsupported record types: %s\n') % s)
5991 unresolved = 0
5991 unresolved = 0
5992 else:
5992 else:
5993 unresolved = [f for f in ms if ms[f] == 'u']
5993 unresolved = [f for f in ms if ms[f] == 'u']
5994
5994
5995 for p in parents:
5995 for p in parents:
5996 # label with log.changeset (instead of log.parent) since this
5996 # label with log.changeset (instead of log.parent) since this
5997 # shows a working directory parent *changeset*:
5997 # shows a working directory parent *changeset*:
5998 # i18n: column positioning for "hg summary"
5998 # i18n: column positioning for "hg summary"
5999 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
5999 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
6000 label=cmdutil._changesetlabels(p))
6000 label=cmdutil._changesetlabels(p))
6001 ui.write(' '.join(p.tags()), label='log.tag')
6001 ui.write(' '.join(p.tags()), label='log.tag')
6002 if p.bookmarks():
6002 if p.bookmarks():
6003 marks.extend(p.bookmarks())
6003 marks.extend(p.bookmarks())
6004 if p.rev() == -1:
6004 if p.rev() == -1:
6005 if not len(repo):
6005 if not len(repo):
6006 ui.write(_(' (empty repository)'))
6006 ui.write(_(' (empty repository)'))
6007 else:
6007 else:
6008 ui.write(_(' (no revision checked out)'))
6008 ui.write(_(' (no revision checked out)'))
6009 if p.troubled():
6009 if p.troubled():
6010 ui.write(' ('
6010 ui.write(' ('
6011 + ', '.join(ui.label(trouble, 'trouble.%s' % trouble)
6011 + ', '.join(ui.label(trouble, 'trouble.%s' % trouble)
6012 for trouble in p.troubles())
6012 for trouble in p.troubles())
6013 + ')')
6013 + ')')
6014 ui.write('\n')
6014 ui.write('\n')
6015 if p.description():
6015 if p.description():
6016 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
6016 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
6017 label='log.summary')
6017 label='log.summary')
6018
6018
6019 branch = ctx.branch()
6019 branch = ctx.branch()
6020 bheads = repo.branchheads(branch)
6020 bheads = repo.branchheads(branch)
6021 # i18n: column positioning for "hg summary"
6021 # i18n: column positioning for "hg summary"
6022 m = _('branch: %s\n') % branch
6022 m = _('branch: %s\n') % branch
6023 if branch != 'default':
6023 if branch != 'default':
6024 ui.write(m, label='log.branch')
6024 ui.write(m, label='log.branch')
6025 else:
6025 else:
6026 ui.status(m, label='log.branch')
6026 ui.status(m, label='log.branch')
6027
6027
6028 if marks:
6028 if marks:
6029 active = repo._activebookmark
6029 active = repo._activebookmark
6030 # i18n: column positioning for "hg summary"
6030 # i18n: column positioning for "hg summary"
6031 ui.write(_('bookmarks:'), label='log.bookmark')
6031 ui.write(_('bookmarks:'), label='log.bookmark')
6032 if active is not None:
6032 if active is not None:
6033 if active in marks:
6033 if active in marks:
6034 ui.write(' *' + active, label=activebookmarklabel)
6034 ui.write(' *' + active, label=activebookmarklabel)
6035 marks.remove(active)
6035 marks.remove(active)
6036 else:
6036 else:
6037 ui.write(' [%s]' % active, label=activebookmarklabel)
6037 ui.write(' [%s]' % active, label=activebookmarklabel)
6038 for m in marks:
6038 for m in marks:
6039 ui.write(' ' + m, label='log.bookmark')
6039 ui.write(' ' + m, label='log.bookmark')
6040 ui.write('\n', label='log.bookmark')
6040 ui.write('\n', label='log.bookmark')
6041
6041
6042 status = repo.status(unknown=True)
6042 status = repo.status(unknown=True)
6043
6043
6044 c = repo.dirstate.copies()
6044 c = repo.dirstate.copies()
6045 copied, renamed = [], []
6045 copied, renamed = [], []
6046 for d, s in c.iteritems():
6046 for d, s in c.iteritems():
6047 if s in status.removed:
6047 if s in status.removed:
6048 status.removed.remove(s)
6048 status.removed.remove(s)
6049 renamed.append(d)
6049 renamed.append(d)
6050 else:
6050 else:
6051 copied.append(d)
6051 copied.append(d)
6052 if d in status.added:
6052 if d in status.added:
6053 status.added.remove(d)
6053 status.added.remove(d)
6054
6054
6055 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
6055 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
6056
6056
6057 labels = [(ui.label(_('%d modified'), 'status.modified'), status.modified),
6057 labels = [(ui.label(_('%d modified'), 'status.modified'), status.modified),
6058 (ui.label(_('%d added'), 'status.added'), status.added),
6058 (ui.label(_('%d added'), 'status.added'), status.added),
6059 (ui.label(_('%d removed'), 'status.removed'), status.removed),
6059 (ui.label(_('%d removed'), 'status.removed'), status.removed),
6060 (ui.label(_('%d renamed'), 'status.copied'), renamed),
6060 (ui.label(_('%d renamed'), 'status.copied'), renamed),
6061 (ui.label(_('%d copied'), 'status.copied'), copied),
6061 (ui.label(_('%d copied'), 'status.copied'), copied),
6062 (ui.label(_('%d deleted'), 'status.deleted'), status.deleted),
6062 (ui.label(_('%d deleted'), 'status.deleted'), status.deleted),
6063 (ui.label(_('%d unknown'), 'status.unknown'), status.unknown),
6063 (ui.label(_('%d unknown'), 'status.unknown'), status.unknown),
6064 (ui.label(_('%d unresolved'), 'resolve.unresolved'), unresolved),
6064 (ui.label(_('%d unresolved'), 'resolve.unresolved'), unresolved),
6065 (ui.label(_('%d subrepos'), 'status.modified'), subs)]
6065 (ui.label(_('%d subrepos'), 'status.modified'), subs)]
6066 t = []
6066 t = []
6067 for l, s in labels:
6067 for l, s in labels:
6068 if s:
6068 if s:
6069 t.append(l % len(s))
6069 t.append(l % len(s))
6070
6070
6071 t = ', '.join(t)
6071 t = ', '.join(t)
6072 cleanworkdir = False
6072 cleanworkdir = False
6073
6073
6074 if repo.vfs.exists('graftstate'):
6074 if repo.vfs.exists('graftstate'):
6075 t += _(' (graft in progress)')
6075 t += _(' (graft in progress)')
6076 if repo.vfs.exists('updatestate'):
6076 if repo.vfs.exists('updatestate'):
6077 t += _(' (interrupted update)')
6077 t += _(' (interrupted update)')
6078 elif len(parents) > 1:
6078 elif len(parents) > 1:
6079 t += _(' (merge)')
6079 t += _(' (merge)')
6080 elif branch != parents[0].branch():
6080 elif branch != parents[0].branch():
6081 t += _(' (new branch)')
6081 t += _(' (new branch)')
6082 elif (parents[0].closesbranch() and
6082 elif (parents[0].closesbranch() and
6083 pnode in repo.branchheads(branch, closed=True)):
6083 pnode in repo.branchheads(branch, closed=True)):
6084 t += _(' (head closed)')
6084 t += _(' (head closed)')
6085 elif not (status.modified or status.added or status.removed or renamed or
6085 elif not (status.modified or status.added or status.removed or renamed or
6086 copied or subs):
6086 copied or subs):
6087 t += _(' (clean)')
6087 t += _(' (clean)')
6088 cleanworkdir = True
6088 cleanworkdir = True
6089 elif pnode not in bheads:
6089 elif pnode not in bheads:
6090 t += _(' (new branch head)')
6090 t += _(' (new branch head)')
6091
6091
6092 if parents:
6092 if parents:
6093 pendingphase = max(p.phase() for p in parents)
6093 pendingphase = max(p.phase() for p in parents)
6094 else:
6094 else:
6095 pendingphase = phases.public
6095 pendingphase = phases.public
6096
6096
6097 if pendingphase > phases.newcommitphase(ui):
6097 if pendingphase > phases.newcommitphase(ui):
6098 t += ' (%s)' % phases.phasenames[pendingphase]
6098 t += ' (%s)' % phases.phasenames[pendingphase]
6099
6099
6100 if cleanworkdir:
6100 if cleanworkdir:
6101 # i18n: column positioning for "hg summary"
6101 # i18n: column positioning for "hg summary"
6102 ui.status(_('commit: %s\n') % t.strip())
6102 ui.status(_('commit: %s\n') % t.strip())
6103 else:
6103 else:
6104 # i18n: column positioning for "hg summary"
6104 # i18n: column positioning for "hg summary"
6105 ui.write(_('commit: %s\n') % t.strip())
6105 ui.write(_('commit: %s\n') % t.strip())
6106
6106
6107 # all ancestors of branch heads - all ancestors of parent = new csets
6107 # all ancestors of branch heads - all ancestors of parent = new csets
6108 new = len(repo.changelog.findmissing([pctx.node() for pctx in parents],
6108 new = len(repo.changelog.findmissing([pctx.node() for pctx in parents],
6109 bheads))
6109 bheads))
6110
6110
6111 if new == 0:
6111 if new == 0:
6112 # i18n: column positioning for "hg summary"
6112 # i18n: column positioning for "hg summary"
6113 ui.status(_('update: (current)\n'))
6113 ui.status(_('update: (current)\n'))
6114 elif pnode not in bheads:
6114 elif pnode not in bheads:
6115 # i18n: column positioning for "hg summary"
6115 # i18n: column positioning for "hg summary"
6116 ui.write(_('update: %d new changesets (update)\n') % new)
6116 ui.write(_('update: %d new changesets (update)\n') % new)
6117 else:
6117 else:
6118 # i18n: column positioning for "hg summary"
6118 # i18n: column positioning for "hg summary"
6119 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
6119 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
6120 (new, len(bheads)))
6120 (new, len(bheads)))
6121
6121
6122 t = []
6122 t = []
6123 draft = len(repo.revs('draft()'))
6123 draft = len(repo.revs('draft()'))
6124 if draft:
6124 if draft:
6125 t.append(_('%d draft') % draft)
6125 t.append(_('%d draft') % draft)
6126 secret = len(repo.revs('secret()'))
6126 secret = len(repo.revs('secret()'))
6127 if secret:
6127 if secret:
6128 t.append(_('%d secret') % secret)
6128 t.append(_('%d secret') % secret)
6129
6129
6130 if draft or secret:
6130 if draft or secret:
6131 ui.status(_('phases: %s\n') % ', '.join(t))
6131 ui.status(_('phases: %s\n') % ', '.join(t))
6132
6132
6133 if obsolete.isenabled(repo, obsolete.createmarkersopt):
6133 if obsolete.isenabled(repo, obsolete.createmarkersopt):
6134 for trouble in ("unstable", "divergent", "bumped"):
6134 for trouble in ("unstable", "divergent", "bumped"):
6135 numtrouble = len(repo.revs(trouble + "()"))
6135 numtrouble = len(repo.revs(trouble + "()"))
6136 # We write all the possibilities to ease translation
6136 # We write all the possibilities to ease translation
6137 troublemsg = {
6137 troublemsg = {
6138 "unstable": _("unstable: %d changesets"),
6138 "unstable": _("unstable: %d changesets"),
6139 "divergent": _("divergent: %d changesets"),
6139 "divergent": _("divergent: %d changesets"),
6140 "bumped": _("bumped: %d changesets"),
6140 "bumped": _("bumped: %d changesets"),
6141 }
6141 }
6142 if numtrouble > 0:
6142 if numtrouble > 0:
6143 ui.status(troublemsg[trouble] % numtrouble + "\n")
6143 ui.status(troublemsg[trouble] % numtrouble + "\n")
6144
6144
6145 cmdutil.summaryhooks(ui, repo)
6145 cmdutil.summaryhooks(ui, repo)
6146
6146
6147 if opts.get('remote'):
6147 if opts.get('remote'):
6148 needsincoming, needsoutgoing = True, True
6148 needsincoming, needsoutgoing = True, True
6149 else:
6149 else:
6150 needsincoming, needsoutgoing = False, False
6150 needsincoming, needsoutgoing = False, False
6151 for i, o in cmdutil.summaryremotehooks(ui, repo, opts, None):
6151 for i, o in cmdutil.summaryremotehooks(ui, repo, opts, None):
6152 if i:
6152 if i:
6153 needsincoming = True
6153 needsincoming = True
6154 if o:
6154 if o:
6155 needsoutgoing = True
6155 needsoutgoing = True
6156 if not needsincoming and not needsoutgoing:
6156 if not needsincoming and not needsoutgoing:
6157 return
6157 return
6158
6158
6159 def getincoming():
6159 def getincoming():
6160 source, branches = hg.parseurl(ui.expandpath('default'))
6160 source, branches = hg.parseurl(ui.expandpath('default'))
6161 sbranch = branches[0]
6161 sbranch = branches[0]
6162 try:
6162 try:
6163 other = hg.peer(repo, {}, source)
6163 other = hg.peer(repo, {}, source)
6164 except error.RepoError:
6164 except error.RepoError:
6165 if opts.get('remote'):
6165 if opts.get('remote'):
6166 raise
6166 raise
6167 return source, sbranch, None, None, None
6167 return source, sbranch, None, None, None
6168 revs, checkout = hg.addbranchrevs(repo, other, branches, None)
6168 revs, checkout = hg.addbranchrevs(repo, other, branches, None)
6169 if revs:
6169 if revs:
6170 revs = [other.lookup(rev) for rev in revs]
6170 revs = [other.lookup(rev) for rev in revs]
6171 ui.debug('comparing with %s\n' % util.hidepassword(source))
6171 ui.debug('comparing with %s\n' % util.hidepassword(source))
6172 repo.ui.pushbuffer()
6172 repo.ui.pushbuffer()
6173 commoninc = discovery.findcommonincoming(repo, other, heads=revs)
6173 commoninc = discovery.findcommonincoming(repo, other, heads=revs)
6174 repo.ui.popbuffer()
6174 repo.ui.popbuffer()
6175 return source, sbranch, other, commoninc, commoninc[1]
6175 return source, sbranch, other, commoninc, commoninc[1]
6176
6176
6177 if needsincoming:
6177 if needsincoming:
6178 source, sbranch, sother, commoninc, incoming = getincoming()
6178 source, sbranch, sother, commoninc, incoming = getincoming()
6179 else:
6179 else:
6180 source = sbranch = sother = commoninc = incoming = None
6180 source = sbranch = sother = commoninc = incoming = None
6181
6181
6182 def getoutgoing():
6182 def getoutgoing():
6183 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
6183 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
6184 dbranch = branches[0]
6184 dbranch = branches[0]
6185 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
6185 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
6186 if source != dest:
6186 if source != dest:
6187 try:
6187 try:
6188 dother = hg.peer(repo, {}, dest)
6188 dother = hg.peer(repo, {}, dest)
6189 except error.RepoError:
6189 except error.RepoError:
6190 if opts.get('remote'):
6190 if opts.get('remote'):
6191 raise
6191 raise
6192 return dest, dbranch, None, None
6192 return dest, dbranch, None, None
6193 ui.debug('comparing with %s\n' % util.hidepassword(dest))
6193 ui.debug('comparing with %s\n' % util.hidepassword(dest))
6194 elif sother is None:
6194 elif sother is None:
6195 # there is no explicit destination peer, but source one is invalid
6195 # there is no explicit destination peer, but source one is invalid
6196 return dest, dbranch, None, None
6196 return dest, dbranch, None, None
6197 else:
6197 else:
6198 dother = sother
6198 dother = sother
6199 if (source != dest or (sbranch is not None and sbranch != dbranch)):
6199 if (source != dest or (sbranch is not None and sbranch != dbranch)):
6200 common = None
6200 common = None
6201 else:
6201 else:
6202 common = commoninc
6202 common = commoninc
6203 if revs:
6203 if revs:
6204 revs = [repo.lookup(rev) for rev in revs]
6204 revs = [repo.lookup(rev) for rev in revs]
6205 repo.ui.pushbuffer()
6205 repo.ui.pushbuffer()
6206 outgoing = discovery.findcommonoutgoing(repo, dother, onlyheads=revs,
6206 outgoing = discovery.findcommonoutgoing(repo, dother, onlyheads=revs,
6207 commoninc=common)
6207 commoninc=common)
6208 repo.ui.popbuffer()
6208 repo.ui.popbuffer()
6209 return dest, dbranch, dother, outgoing
6209 return dest, dbranch, dother, outgoing
6210
6210
6211 if needsoutgoing:
6211 if needsoutgoing:
6212 dest, dbranch, dother, outgoing = getoutgoing()
6212 dest, dbranch, dother, outgoing = getoutgoing()
6213 else:
6213 else:
6214 dest = dbranch = dother = outgoing = None
6214 dest = dbranch = dother = outgoing = None
6215
6215
6216 if opts.get('remote'):
6216 if opts.get('remote'):
6217 t = []
6217 t = []
6218 if incoming:
6218 if incoming:
6219 t.append(_('1 or more incoming'))
6219 t.append(_('1 or more incoming'))
6220 o = outgoing.missing
6220 o = outgoing.missing
6221 if o:
6221 if o:
6222 t.append(_('%d outgoing') % len(o))
6222 t.append(_('%d outgoing') % len(o))
6223 other = dother or sother
6223 other = dother or sother
6224 if 'bookmarks' in other.listkeys('namespaces'):
6224 if 'bookmarks' in other.listkeys('namespaces'):
6225 counts = bookmarks.summary(repo, other)
6225 counts = bookmarks.summary(repo, other)
6226 if counts[0] > 0:
6226 if counts[0] > 0:
6227 t.append(_('%d incoming bookmarks') % counts[0])
6227 t.append(_('%d incoming bookmarks') % counts[0])
6228 if counts[1] > 0:
6228 if counts[1] > 0:
6229 t.append(_('%d outgoing bookmarks') % counts[1])
6229 t.append(_('%d outgoing bookmarks') % counts[1])
6230
6230
6231 if t:
6231 if t:
6232 # i18n: column positioning for "hg summary"
6232 # i18n: column positioning for "hg summary"
6233 ui.write(_('remote: %s\n') % (', '.join(t)))
6233 ui.write(_('remote: %s\n') % (', '.join(t)))
6234 else:
6234 else:
6235 # i18n: column positioning for "hg summary"
6235 # i18n: column positioning for "hg summary"
6236 ui.status(_('remote: (synced)\n'))
6236 ui.status(_('remote: (synced)\n'))
6237
6237
6238 cmdutil.summaryremotehooks(ui, repo, opts,
6238 cmdutil.summaryremotehooks(ui, repo, opts,
6239 ((source, sbranch, sother, commoninc),
6239 ((source, sbranch, sother, commoninc),
6240 (dest, dbranch, dother, outgoing)))
6240 (dest, dbranch, dother, outgoing)))
6241
6241
6242 @command('tag',
6242 @command('tag',
6243 [('f', 'force', None, _('force tag')),
6243 [('f', 'force', None, _('force tag')),
6244 ('l', 'local', None, _('make the tag local')),
6244 ('l', 'local', None, _('make the tag local')),
6245 ('r', 'rev', '', _('revision to tag'), _('REV')),
6245 ('r', 'rev', '', _('revision to tag'), _('REV')),
6246 ('', 'remove', None, _('remove a tag')),
6246 ('', 'remove', None, _('remove a tag')),
6247 # -l/--local is already there, commitopts cannot be used
6247 # -l/--local is already there, commitopts cannot be used
6248 ('e', 'edit', None, _('invoke editor on commit messages')),
6248 ('e', 'edit', None, _('invoke editor on commit messages')),
6249 ('m', 'message', '', _('use text as commit message'), _('TEXT')),
6249 ('m', 'message', '', _('use text as commit message'), _('TEXT')),
6250 ] + commitopts2,
6250 ] + commitopts2,
6251 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'))
6251 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'))
6252 def tag(ui, repo, name1, *names, **opts):
6252 def tag(ui, repo, name1, *names, **opts):
6253 """add one or more tags for the current or given revision
6253 """add one or more tags for the current or given revision
6254
6254
6255 Name a particular revision using <name>.
6255 Name a particular revision using <name>.
6256
6256
6257 Tags are used to name particular revisions of the repository and are
6257 Tags are used to name particular revisions of the repository and are
6258 very useful to compare different revisions, to go back to significant
6258 very useful to compare different revisions, to go back to significant
6259 earlier versions or to mark branch points as releases, etc. Changing
6259 earlier versions or to mark branch points as releases, etc. Changing
6260 an existing tag is normally disallowed; use -f/--force to override.
6260 an existing tag is normally disallowed; use -f/--force to override.
6261
6261
6262 If no revision is given, the parent of the working directory is
6262 If no revision is given, the parent of the working directory is
6263 used.
6263 used.
6264
6264
6265 To facilitate version control, distribution, and merging of tags,
6265 To facilitate version control, distribution, and merging of tags,
6266 they are stored as a file named ".hgtags" which is managed similarly
6266 they are stored as a file named ".hgtags" which is managed similarly
6267 to other project files and can be hand-edited if necessary. This
6267 to other project files and can be hand-edited if necessary. This
6268 also means that tagging creates a new commit. The file
6268 also means that tagging creates a new commit. The file
6269 ".hg/localtags" is used for local tags (not shared among
6269 ".hg/localtags" is used for local tags (not shared among
6270 repositories).
6270 repositories).
6271
6271
6272 Tag commits are usually made at the head of a branch. If the parent
6272 Tag commits are usually made at the head of a branch. If the parent
6273 of the working directory is not a branch head, :hg:`tag` aborts; use
6273 of the working directory is not a branch head, :hg:`tag` aborts; use
6274 -f/--force to force the tag commit to be based on a non-head
6274 -f/--force to force the tag commit to be based on a non-head
6275 changeset.
6275 changeset.
6276
6276
6277 See :hg:`help dates` for a list of formats valid for -d/--date.
6277 See :hg:`help dates` for a list of formats valid for -d/--date.
6278
6278
6279 Since tag names have priority over branch names during revision
6279 Since tag names have priority over branch names during revision
6280 lookup, using an existing branch name as a tag name is discouraged.
6280 lookup, using an existing branch name as a tag name is discouraged.
6281
6281
6282 Returns 0 on success.
6282 Returns 0 on success.
6283 """
6283 """
6284 wlock = lock = None
6284 wlock = lock = None
6285 try:
6285 try:
6286 wlock = repo.wlock()
6286 wlock = repo.wlock()
6287 lock = repo.lock()
6287 lock = repo.lock()
6288 rev_ = "."
6288 rev_ = "."
6289 names = [t.strip() for t in (name1,) + names]
6289 names = [t.strip() for t in (name1,) + names]
6290 if len(names) != len(set(names)):
6290 if len(names) != len(set(names)):
6291 raise error.Abort(_('tag names must be unique'))
6291 raise error.Abort(_('tag names must be unique'))
6292 for n in names:
6292 for n in names:
6293 scmutil.checknewlabel(repo, n, 'tag')
6293 scmutil.checknewlabel(repo, n, 'tag')
6294 if not n:
6294 if not n:
6295 raise error.Abort(_('tag names cannot consist entirely of '
6295 raise error.Abort(_('tag names cannot consist entirely of '
6296 'whitespace'))
6296 'whitespace'))
6297 if opts.get('rev') and opts.get('remove'):
6297 if opts.get('rev') and opts.get('remove'):
6298 raise error.Abort(_("--rev and --remove are incompatible"))
6298 raise error.Abort(_("--rev and --remove are incompatible"))
6299 if opts.get('rev'):
6299 if opts.get('rev'):
6300 rev_ = opts['rev']
6300 rev_ = opts['rev']
6301 message = opts.get('message')
6301 message = opts.get('message')
6302 if opts.get('remove'):
6302 if opts.get('remove'):
6303 if opts.get('local'):
6303 if opts.get('local'):
6304 expectedtype = 'local'
6304 expectedtype = 'local'
6305 else:
6305 else:
6306 expectedtype = 'global'
6306 expectedtype = 'global'
6307
6307
6308 for n in names:
6308 for n in names:
6309 if not repo.tagtype(n):
6309 if not repo.tagtype(n):
6310 raise error.Abort(_("tag '%s' does not exist") % n)
6310 raise error.Abort(_("tag '%s' does not exist") % n)
6311 if repo.tagtype(n) != expectedtype:
6311 if repo.tagtype(n) != expectedtype:
6312 if expectedtype == 'global':
6312 if expectedtype == 'global':
6313 raise error.Abort(_("tag '%s' is not a global tag") % n)
6313 raise error.Abort(_("tag '%s' is not a global tag") % n)
6314 else:
6314 else:
6315 raise error.Abort(_("tag '%s' is not a local tag") % n)
6315 raise error.Abort(_("tag '%s' is not a local tag") % n)
6316 rev_ = 'null'
6316 rev_ = 'null'
6317 if not message:
6317 if not message:
6318 # we don't translate commit messages
6318 # we don't translate commit messages
6319 message = 'Removed tag %s' % ', '.join(names)
6319 message = 'Removed tag %s' % ', '.join(names)
6320 elif not opts.get('force'):
6320 elif not opts.get('force'):
6321 for n in names:
6321 for n in names:
6322 if n in repo.tags():
6322 if n in repo.tags():
6323 raise error.Abort(_("tag '%s' already exists "
6323 raise error.Abort(_("tag '%s' already exists "
6324 "(use -f to force)") % n)
6324 "(use -f to force)") % n)
6325 if not opts.get('local'):
6325 if not opts.get('local'):
6326 p1, p2 = repo.dirstate.parents()
6326 p1, p2 = repo.dirstate.parents()
6327 if p2 != nullid:
6327 if p2 != nullid:
6328 raise error.Abort(_('uncommitted merge'))
6328 raise error.Abort(_('uncommitted merge'))
6329 bheads = repo.branchheads()
6329 bheads = repo.branchheads()
6330 if not opts.get('force') and bheads and p1 not in bheads:
6330 if not opts.get('force') and bheads and p1 not in bheads:
6331 raise error.Abort(_('working directory is not at a branch head '
6331 raise error.Abort(_('working directory is not at a branch head '
6332 '(use -f to force)'))
6332 '(use -f to force)'))
6333 r = scmutil.revsingle(repo, rev_).node()
6333 r = scmutil.revsingle(repo, rev_).node()
6334
6334
6335 if not message:
6335 if not message:
6336 # we don't translate commit messages
6336 # we don't translate commit messages
6337 message = ('Added tag %s for changeset %s' %
6337 message = ('Added tag %s for changeset %s' %
6338 (', '.join(names), short(r)))
6338 (', '.join(names), short(r)))
6339
6339
6340 date = opts.get('date')
6340 date = opts.get('date')
6341 if date:
6341 if date:
6342 date = util.parsedate(date)
6342 date = util.parsedate(date)
6343
6343
6344 if opts.get('remove'):
6344 if opts.get('remove'):
6345 editform = 'tag.remove'
6345 editform = 'tag.remove'
6346 else:
6346 else:
6347 editform = 'tag.add'
6347 editform = 'tag.add'
6348 editor = cmdutil.getcommiteditor(editform=editform, **opts)
6348 editor = cmdutil.getcommiteditor(editform=editform, **opts)
6349
6349
6350 # don't allow tagging the null rev
6350 # don't allow tagging the null rev
6351 if (not opts.get('remove') and
6351 if (not opts.get('remove') and
6352 scmutil.revsingle(repo, rev_).rev() == nullrev):
6352 scmutil.revsingle(repo, rev_).rev() == nullrev):
6353 raise error.Abort(_("cannot tag null revision"))
6353 raise error.Abort(_("cannot tag null revision"))
6354
6354
6355 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date,
6355 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date,
6356 editor=editor)
6356 editor=editor)
6357 finally:
6357 finally:
6358 release(lock, wlock)
6358 release(lock, wlock)
6359
6359
6360 @command('tags', formatteropts, '')
6360 @command('tags', formatteropts, '')
6361 def tags(ui, repo, **opts):
6361 def tags(ui, repo, **opts):
6362 """list repository tags
6362 """list repository tags
6363
6363
6364 This lists both regular and local tags. When the -v/--verbose
6364 This lists both regular and local tags. When the -v/--verbose
6365 switch is used, a third column "local" is printed for local tags.
6365 switch is used, a third column "local" is printed for local tags.
6366 When the -q/--quiet switch is used, only the tag name is printed.
6366 When the -q/--quiet switch is used, only the tag name is printed.
6367
6367
6368 Returns 0 on success.
6368 Returns 0 on success.
6369 """
6369 """
6370
6370
6371 fm = ui.formatter('tags', opts)
6371 fm = ui.formatter('tags', opts)
6372 hexfunc = fm.hexfunc
6372 hexfunc = fm.hexfunc
6373 tagtype = ""
6373 tagtype = ""
6374
6374
6375 for t, n in reversed(repo.tagslist()):
6375 for t, n in reversed(repo.tagslist()):
6376 hn = hexfunc(n)
6376 hn = hexfunc(n)
6377 label = 'tags.normal'
6377 label = 'tags.normal'
6378 tagtype = ''
6378 tagtype = ''
6379 if repo.tagtype(t) == 'local':
6379 if repo.tagtype(t) == 'local':
6380 label = 'tags.local'
6380 label = 'tags.local'
6381 tagtype = 'local'
6381 tagtype = 'local'
6382
6382
6383 fm.startitem()
6383 fm.startitem()
6384 fm.write('tag', '%s', t, label=label)
6384 fm.write('tag', '%s', t, label=label)
6385 fmt = " " * (30 - encoding.colwidth(t)) + ' %5d:%s'
6385 fmt = " " * (30 - encoding.colwidth(t)) + ' %5d:%s'
6386 fm.condwrite(not ui.quiet, 'rev node', fmt,
6386 fm.condwrite(not ui.quiet, 'rev node', fmt,
6387 repo.changelog.rev(n), hn, label=label)
6387 repo.changelog.rev(n), hn, label=label)
6388 fm.condwrite(ui.verbose and tagtype, 'type', ' %s',
6388 fm.condwrite(ui.verbose and tagtype, 'type', ' %s',
6389 tagtype, label=label)
6389 tagtype, label=label)
6390 fm.plain('\n')
6390 fm.plain('\n')
6391 fm.end()
6391 fm.end()
6392
6392
6393 @command('tip',
6393 @command('tip',
6394 [('p', 'patch', None, _('show patch')),
6394 [('p', 'patch', None, _('show patch')),
6395 ('g', 'git', None, _('use git extended diff format')),
6395 ('g', 'git', None, _('use git extended diff format')),
6396 ] + templateopts,
6396 ] + templateopts,
6397 _('[-p] [-g]'))
6397 _('[-p] [-g]'))
6398 def tip(ui, repo, **opts):
6398 def tip(ui, repo, **opts):
6399 """show the tip revision (DEPRECATED)
6399 """show the tip revision (DEPRECATED)
6400
6400
6401 The tip revision (usually just called the tip) is the changeset
6401 The tip revision (usually just called the tip) is the changeset
6402 most recently added to the repository (and therefore the most
6402 most recently added to the repository (and therefore the most
6403 recently changed head).
6403 recently changed head).
6404
6404
6405 If you have just made a commit, that commit will be the tip. If
6405 If you have just made a commit, that commit will be the tip. If
6406 you have just pulled changes from another repository, the tip of
6406 you have just pulled changes from another repository, the tip of
6407 that repository becomes the current tip. The "tip" tag is special
6407 that repository becomes the current tip. The "tip" tag is special
6408 and cannot be renamed or assigned to a different changeset.
6408 and cannot be renamed or assigned to a different changeset.
6409
6409
6410 This command is deprecated, please use :hg:`heads` instead.
6410 This command is deprecated, please use :hg:`heads` instead.
6411
6411
6412 Returns 0 on success.
6412 Returns 0 on success.
6413 """
6413 """
6414 displayer = cmdutil.show_changeset(ui, repo, opts)
6414 displayer = cmdutil.show_changeset(ui, repo, opts)
6415 displayer.show(repo['tip'])
6415 displayer.show(repo['tip'])
6416 displayer.close()
6416 displayer.close()
6417
6417
6418 @command('unbundle',
6418 @command('unbundle',
6419 [('u', 'update', None,
6419 [('u', 'update', None,
6420 _('update to new branch head if changesets were unbundled'))],
6420 _('update to new branch head if changesets were unbundled'))],
6421 _('[-u] FILE...'))
6421 _('[-u] FILE...'))
6422 def unbundle(ui, repo, fname1, *fnames, **opts):
6422 def unbundle(ui, repo, fname1, *fnames, **opts):
6423 """apply one or more changegroup files
6423 """apply one or more changegroup files
6424
6424
6425 Apply one or more compressed changegroup files generated by the
6425 Apply one or more compressed changegroup files generated by the
6426 bundle command.
6426 bundle command.
6427
6427
6428 Returns 0 on success, 1 if an update has unresolved files.
6428 Returns 0 on success, 1 if an update has unresolved files.
6429 """
6429 """
6430 fnames = (fname1,) + fnames
6430 fnames = (fname1,) + fnames
6431
6431
6432 with repo.lock():
6432 with repo.lock():
6433 for fname in fnames:
6433 for fname in fnames:
6434 f = hg.openpath(ui, fname)
6434 f = hg.openpath(ui, fname)
6435 gen = exchange.readbundle(ui, f, fname)
6435 gen = exchange.readbundle(ui, f, fname)
6436 if isinstance(gen, bundle2.unbundle20):
6436 if isinstance(gen, bundle2.unbundle20):
6437 tr = repo.transaction('unbundle')
6437 tr = repo.transaction('unbundle')
6438 try:
6438 try:
6439 op = bundle2.applybundle(repo, gen, tr, source='unbundle',
6439 op = bundle2.applybundle(repo, gen, tr, source='unbundle',
6440 url='bundle:' + fname)
6440 url='bundle:' + fname)
6441 tr.close()
6441 tr.close()
6442 except error.BundleUnknownFeatureError as exc:
6442 except error.BundleUnknownFeatureError as exc:
6443 raise error.Abort(_('%s: unknown bundle feature, %s')
6443 raise error.Abort(_('%s: unknown bundle feature, %s')
6444 % (fname, exc),
6444 % (fname, exc),
6445 hint=_("see https://mercurial-scm.org/"
6445 hint=_("see https://mercurial-scm.org/"
6446 "wiki/BundleFeature for more "
6446 "wiki/BundleFeature for more "
6447 "information"))
6447 "information"))
6448 finally:
6448 finally:
6449 if tr:
6449 if tr:
6450 tr.release()
6450 tr.release()
6451 changes = [r.get('return', 0)
6451 changes = [r.get('return', 0)
6452 for r in op.records['changegroup']]
6452 for r in op.records['changegroup']]
6453 modheads = changegroup.combineresults(changes)
6453 modheads = changegroup.combineresults(changes)
6454 elif isinstance(gen, streamclone.streamcloneapplier):
6454 elif isinstance(gen, streamclone.streamcloneapplier):
6455 raise error.Abort(
6455 raise error.Abort(
6456 _('packed bundles cannot be applied with '
6456 _('packed bundles cannot be applied with '
6457 '"hg unbundle"'),
6457 '"hg unbundle"'),
6458 hint=_('use "hg debugapplystreamclonebundle"'))
6458 hint=_('use "hg debugapplystreamclonebundle"'))
6459 else:
6459 else:
6460 modheads = gen.apply(repo, 'unbundle', 'bundle:' + fname)
6460 modheads = gen.apply(repo, 'unbundle', 'bundle:' + fname)
6461
6461
6462 return postincoming(ui, repo, modheads, opts.get('update'), None, None)
6462 return postincoming(ui, repo, modheads, opts.get('update'), None, None)
6463
6463
6464 @command('^update|up|checkout|co',
6464 @command('^update|up|checkout|co',
6465 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
6465 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
6466 ('c', 'check', None, _('require clean working directory')),
6466 ('c', 'check', None, _('require clean working directory')),
6467 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
6467 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
6468 ('r', 'rev', '', _('revision'), _('REV'))
6468 ('r', 'rev', '', _('revision'), _('REV'))
6469 ] + mergetoolopts,
6469 ] + mergetoolopts,
6470 _('[-c] [-C] [-d DATE] [[-r] REV]'))
6470 _('[-c] [-C] [-d DATE] [[-r] REV]'))
6471 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False,
6471 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False,
6472 tool=None):
6472 tool=None):
6473 """update working directory (or switch revisions)
6473 """update working directory (or switch revisions)
6474
6474
6475 Update the repository's working directory to the specified
6475 Update the repository's working directory to the specified
6476 changeset. If no changeset is specified, update to the tip of the
6476 changeset. If no changeset is specified, update to the tip of the
6477 current named branch and move the active bookmark (see :hg:`help
6477 current named branch and move the active bookmark (see :hg:`help
6478 bookmarks`).
6478 bookmarks`).
6479
6479
6480 Update sets the working directory's parent revision to the specified
6480 Update sets the working directory's parent revision to the specified
6481 changeset (see :hg:`help parents`).
6481 changeset (see :hg:`help parents`).
6482
6482
6483 If the changeset is not a descendant or ancestor of the working
6483 If the changeset is not a descendant or ancestor of the working
6484 directory's parent and there are uncommitted changes, the update is
6484 directory's parent and there are uncommitted changes, the update is
6485 aborted. With the -c/--check option, the working directory is checked
6485 aborted. With the -c/--check option, the working directory is checked
6486 for uncommitted changes; if none are found, the working directory is
6486 for uncommitted changes; if none are found, the working directory is
6487 updated to the specified changeset.
6487 updated to the specified changeset.
6488
6488
6489 .. container:: verbose
6489 .. container:: verbose
6490
6490
6491 The following rules apply when the working directory contains
6491 The following rules apply when the working directory contains
6492 uncommitted changes:
6492 uncommitted changes:
6493
6493
6494 1. If neither -c/--check nor -C/--clean is specified, and if
6494 1. If neither -c/--check nor -C/--clean is specified, and if
6495 the requested changeset is an ancestor or descendant of
6495 the requested changeset is an ancestor or descendant of
6496 the working directory's parent, the uncommitted changes
6496 the working directory's parent, the uncommitted changes
6497 are merged into the requested changeset and the merged
6497 are merged into the requested changeset and the merged
6498 result is left uncommitted. If the requested changeset is
6498 result is left uncommitted. If the requested changeset is
6499 not an ancestor or descendant (that is, it is on another
6499 not an ancestor or descendant (that is, it is on another
6500 branch), the update is aborted and the uncommitted changes
6500 branch), the update is aborted and the uncommitted changes
6501 are preserved.
6501 are preserved.
6502
6502
6503 2. With the -c/--check option, the update is aborted and the
6503 2. With the -c/--check option, the update is aborted and the
6504 uncommitted changes are preserved.
6504 uncommitted changes are preserved.
6505
6505
6506 3. With the -C/--clean option, uncommitted changes are discarded and
6506 3. With the -C/--clean option, uncommitted changes are discarded and
6507 the working directory is updated to the requested changeset.
6507 the working directory is updated to the requested changeset.
6508
6508
6509 To cancel an uncommitted merge (and lose your changes), use
6509 To cancel an uncommitted merge (and lose your changes), use
6510 :hg:`update --clean .`.
6510 :hg:`update --clean .`.
6511
6511
6512 Use null as the changeset to remove the working directory (like
6512 Use null as the changeset to remove the working directory (like
6513 :hg:`clone -U`).
6513 :hg:`clone -U`).
6514
6514
6515 If you want to revert just one file to an older revision, use
6515 If you want to revert just one file to an older revision, use
6516 :hg:`revert [-r REV] NAME`.
6516 :hg:`revert [-r REV] NAME`.
6517
6517
6518 See :hg:`help dates` for a list of formats valid for -d/--date.
6518 See :hg:`help dates` for a list of formats valid for -d/--date.
6519
6519
6520 Returns 0 on success, 1 if there are unresolved files.
6520 Returns 0 on success, 1 if there are unresolved files.
6521 """
6521 """
6522 if rev and node:
6522 if rev and node:
6523 raise error.Abort(_("please specify just one revision"))
6523 raise error.Abort(_("please specify just one revision"))
6524
6524
6525 if rev is None or rev == '':
6525 if rev is None or rev == '':
6526 rev = node
6526 rev = node
6527
6527
6528 if date and rev is not None:
6528 if date and rev is not None:
6529 raise error.Abort(_("you can't specify a revision and a date"))
6529 raise error.Abort(_("you can't specify a revision and a date"))
6530
6530
6531 if check and clean:
6531 if check and clean:
6532 raise error.Abort(_("cannot specify both -c/--check and -C/--clean"))
6532 raise error.Abort(_("cannot specify both -c/--check and -C/--clean"))
6533
6533
6534 with repo.wlock():
6534 with repo.wlock():
6535 cmdutil.clearunfinished(repo)
6535 cmdutil.clearunfinished(repo)
6536
6536
6537 if date:
6537 if date:
6538 rev = cmdutil.finddate(ui, repo, date)
6538 rev = cmdutil.finddate(ui, repo, date)
6539
6539
6540 # if we defined a bookmark, we have to remember the original name
6540 # if we defined a bookmark, we have to remember the original name
6541 brev = rev
6541 brev = rev
6542 rev = scmutil.revsingle(repo, rev, rev).rev()
6542 rev = scmutil.revsingle(repo, rev, rev).rev()
6543
6543
6544 if check:
6544 if check:
6545 cmdutil.bailifchanged(repo, merge=False)
6545 cmdutil.bailifchanged(repo, merge=False)
6546
6546
6547 repo.ui.setconfig('ui', 'forcemerge', tool, 'update')
6547 repo.ui.setconfig('ui', 'forcemerge', tool, 'update')
6548
6548
6549 return hg.updatetotally(ui, repo, rev, brev, clean=clean, check=check)
6549 return hg.updatetotally(ui, repo, rev, brev, clean=clean, check=check)
6550
6550
6551 @command('verify', [])
6551 @command('verify', [])
6552 def verify(ui, repo):
6552 def verify(ui, repo):
6553 """verify the integrity of the repository
6553 """verify the integrity of the repository
6554
6554
6555 Verify the integrity of the current repository.
6555 Verify the integrity of the current repository.
6556
6556
6557 This will perform an extensive check of the repository's
6557 This will perform an extensive check of the repository's
6558 integrity, validating the hashes and checksums of each entry in
6558 integrity, validating the hashes and checksums of each entry in
6559 the changelog, manifest, and tracked files, as well as the
6559 the changelog, manifest, and tracked files, as well as the
6560 integrity of their crosslinks and indices.
6560 integrity of their crosslinks and indices.
6561
6561
6562 Please see https://mercurial-scm.org/wiki/RepositoryCorruption
6562 Please see https://mercurial-scm.org/wiki/RepositoryCorruption
6563 for more information about recovery from corruption of the
6563 for more information about recovery from corruption of the
6564 repository.
6564 repository.
6565
6565
6566 Returns 0 on success, 1 if errors are encountered.
6566 Returns 0 on success, 1 if errors are encountered.
6567 """
6567 """
6568 return hg.verify(repo)
6568 return hg.verify(repo)
6569
6569
6570 @command('version', [] + formatteropts, norepo=True)
6570 @command('version', [] + formatteropts, norepo=True)
6571 def version_(ui, **opts):
6571 def version_(ui, **opts):
6572 """output version and copyright information"""
6572 """output version and copyright information"""
6573 fm = ui.formatter("version", opts)
6573 fm = ui.formatter("version", opts)
6574 fm.startitem()
6574 fm.startitem()
6575 fm.write("ver", _("Mercurial Distributed SCM (version %s)\n"),
6575 fm.write("ver", _("Mercurial Distributed SCM (version %s)\n"),
6576 util.version())
6576 util.version())
6577 license = _(
6577 license = _(
6578 "(see https://mercurial-scm.org for more information)\n"
6578 "(see https://mercurial-scm.org for more information)\n"
6579 "\nCopyright (C) 2005-2016 Matt Mackall and others\n"
6579 "\nCopyright (C) 2005-2017 Matt Mackall and others\n"
6580 "This is free software; see the source for copying conditions. "
6580 "This is free software; see the source for copying conditions. "
6581 "There is NO\nwarranty; "
6581 "There is NO\nwarranty; "
6582 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
6582 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
6583 )
6583 )
6584 if not ui.quiet:
6584 if not ui.quiet:
6585 fm.plain(license)
6585 fm.plain(license)
6586
6586
6587 if ui.verbose:
6587 if ui.verbose:
6588 fm.plain(_("\nEnabled extensions:\n\n"))
6588 fm.plain(_("\nEnabled extensions:\n\n"))
6589 # format names and versions into columns
6589 # format names and versions into columns
6590 names = []
6590 names = []
6591 vers = []
6591 vers = []
6592 isinternals = []
6592 isinternals = []
6593 for name, module in extensions.extensions():
6593 for name, module in extensions.extensions():
6594 names.append(name)
6594 names.append(name)
6595 vers.append(extensions.moduleversion(module) or None)
6595 vers.append(extensions.moduleversion(module) or None)
6596 isinternals.append(extensions.ismoduleinternal(module))
6596 isinternals.append(extensions.ismoduleinternal(module))
6597 fn = fm.nested("extensions")
6597 fn = fm.nested("extensions")
6598 if names:
6598 if names:
6599 namefmt = " %%-%ds " % max(len(n) for n in names)
6599 namefmt = " %%-%ds " % max(len(n) for n in names)
6600 places = [_("external"), _("internal")]
6600 places = [_("external"), _("internal")]
6601 for n, v, p in zip(names, vers, isinternals):
6601 for n, v, p in zip(names, vers, isinternals):
6602 fn.startitem()
6602 fn.startitem()
6603 fn.condwrite(ui.verbose, "name", namefmt, n)
6603 fn.condwrite(ui.verbose, "name", namefmt, n)
6604 if ui.verbose:
6604 if ui.verbose:
6605 fn.plain("%s " % places[p])
6605 fn.plain("%s " % places[p])
6606 fn.data(bundled=p)
6606 fn.data(bundled=p)
6607 fn.condwrite(ui.verbose and v, "ver", "%s", v)
6607 fn.condwrite(ui.verbose and v, "ver", "%s", v)
6608 if ui.verbose:
6608 if ui.verbose:
6609 fn.plain("\n")
6609 fn.plain("\n")
6610 fn.end()
6610 fn.end()
6611 fm.end()
6611 fm.end()
6612
6612
6613 def loadcmdtable(ui, name, cmdtable):
6613 def loadcmdtable(ui, name, cmdtable):
6614 """Load command functions from specified cmdtable
6614 """Load command functions from specified cmdtable
6615 """
6615 """
6616 overrides = [cmd for cmd in cmdtable if cmd in table]
6616 overrides = [cmd for cmd in cmdtable if cmd in table]
6617 if overrides:
6617 if overrides:
6618 ui.warn(_("extension '%s' overrides commands: %s\n")
6618 ui.warn(_("extension '%s' overrides commands: %s\n")
6619 % (name, " ".join(overrides)))
6619 % (name, " ".join(overrides)))
6620 table.update(cmdtable)
6620 table.update(cmdtable)
@@ -1,119 +1,119 b''
1 ====
1 ====
2 hg
2 hg
3 ====
3 ====
4
4
5 ---------------------------------------
5 ---------------------------------------
6 Mercurial source code management system
6 Mercurial source code management system
7 ---------------------------------------
7 ---------------------------------------
8
8
9 :Author: Matt Mackall <mpm@selenic.com>
9 :Author: Matt Mackall <mpm@selenic.com>
10 :Organization: Mercurial
10 :Organization: Mercurial
11 :Manual section: 1
11 :Manual section: 1
12 :Manual group: Mercurial Manual
12 :Manual group: Mercurial Manual
13
13
14 .. contents::
14 .. contents::
15 :backlinks: top
15 :backlinks: top
16 :class: htmlonly
16 :class: htmlonly
17 :depth: 1
17 :depth: 1
18
18
19
19
20 Synopsis
20 Synopsis
21 """"""""
21 """"""""
22 **hg** *command* [*option*]... [*argument*]...
22 **hg** *command* [*option*]... [*argument*]...
23
23
24 Description
24 Description
25 """""""""""
25 """""""""""
26 The **hg** command provides a command line interface to the Mercurial
26 The **hg** command provides a command line interface to the Mercurial
27 system.
27 system.
28
28
29 Command Elements
29 Command Elements
30 """"""""""""""""
30 """"""""""""""""
31
31
32 files...
32 files...
33 indicates one or more filename or relative path filenames; see
33 indicates one or more filename or relative path filenames; see
34 `File Name Patterns`_ for information on pattern matching
34 `File Name Patterns`_ for information on pattern matching
35
35
36 path
36 path
37 indicates a path on the local machine
37 indicates a path on the local machine
38
38
39 revision
39 revision
40 indicates a changeset which can be specified as a changeset
40 indicates a changeset which can be specified as a changeset
41 revision number, a tag, or a unique substring of the changeset
41 revision number, a tag, or a unique substring of the changeset
42 hash value
42 hash value
43
43
44 repository path
44 repository path
45 either the pathname of a local repository or the URI of a remote
45 either the pathname of a local repository or the URI of a remote
46 repository.
46 repository.
47
47
48 .. include:: hg.1.gendoc.txt
48 .. include:: hg.1.gendoc.txt
49
49
50 Files
50 Files
51 """""
51 """""
52
52
53 ``/etc/mercurial/hgrc``, ``$HOME/.hgrc``, ``.hg/hgrc``
53 ``/etc/mercurial/hgrc``, ``$HOME/.hgrc``, ``.hg/hgrc``
54 This file contains defaults and configuration. Values in
54 This file contains defaults and configuration. Values in
55 ``.hg/hgrc`` override those in ``$HOME/.hgrc``, and these override
55 ``.hg/hgrc`` override those in ``$HOME/.hgrc``, and these override
56 settings made in the global ``/etc/mercurial/hgrc`` configuration.
56 settings made in the global ``/etc/mercurial/hgrc`` configuration.
57 See |hgrc(5)|_ for details of the contents and format of these
57 See |hgrc(5)|_ for details of the contents and format of these
58 files.
58 files.
59
59
60 ``.hgignore``
60 ``.hgignore``
61 This file contains regular expressions (one per line) that
61 This file contains regular expressions (one per line) that
62 describe file names that should be ignored by **hg**. For details,
62 describe file names that should be ignored by **hg**. For details,
63 see |hgignore(5)|_.
63 see |hgignore(5)|_.
64
64
65 ``.hgsub``
65 ``.hgsub``
66 This file defines the locations of all subrepositories, and
66 This file defines the locations of all subrepositories, and
67 tells where the subrepository checkouts came from. For details, see
67 tells where the subrepository checkouts came from. For details, see
68 :hg:`help subrepos`.
68 :hg:`help subrepos`.
69
69
70 ``.hgsubstate``
70 ``.hgsubstate``
71 This file is where Mercurial stores all nested repository states. *NB: This
71 This file is where Mercurial stores all nested repository states. *NB: This
72 file should not be edited manually.*
72 file should not be edited manually.*
73
73
74 ``.hgtags``
74 ``.hgtags``
75 This file contains changeset hash values and text tag names (one
75 This file contains changeset hash values and text tag names (one
76 of each separated by spaces) that correspond to tagged versions of
76 of each separated by spaces) that correspond to tagged versions of
77 the repository contents. The file content is encoded using UTF-8.
77 the repository contents. The file content is encoded using UTF-8.
78
78
79 ``.hg/last-message.txt``
79 ``.hg/last-message.txt``
80 This file is used by :hg:`commit` to store a backup of the commit message
80 This file is used by :hg:`commit` to store a backup of the commit message
81 in case the commit fails.
81 in case the commit fails.
82
82
83 ``.hg/localtags``
83 ``.hg/localtags``
84 This file can be used to define local tags which are not shared among
84 This file can be used to define local tags which are not shared among
85 repositories. The file format is the same as for ``.hgtags``, but it is
85 repositories. The file format is the same as for ``.hgtags``, but it is
86 encoded using the local system encoding.
86 encoded using the local system encoding.
87
87
88 Some commands (e.g. revert) produce backup files ending in ``.orig``,
88 Some commands (e.g. revert) produce backup files ending in ``.orig``,
89 if the ``.orig`` file already exists and is not tracked by Mercurial,
89 if the ``.orig`` file already exists and is not tracked by Mercurial,
90 it will be overwritten.
90 it will be overwritten.
91
91
92 Bugs
92 Bugs
93 """"
93 """"
94 Probably lots, please post them to the mailing list (see Resources_
94 Probably lots, please post them to the mailing list (see Resources_
95 below) when you find them.
95 below) when you find them.
96
96
97 See Also
97 See Also
98 """"""""
98 """"""""
99 |hgignore(5)|_, |hgrc(5)|_
99 |hgignore(5)|_, |hgrc(5)|_
100
100
101 Author
101 Author
102 """"""
102 """"""
103 Written by Matt Mackall <mpm@selenic.com>
103 Written by Matt Mackall <mpm@selenic.com>
104
104
105 Resources
105 Resources
106 """""""""
106 """""""""
107 Main Web Site: https://mercurial-scm.org/
107 Main Web Site: https://mercurial-scm.org/
108
108
109 Source code repository: https://www.mercurial-scm.org/repo/hg
109 Source code repository: https://www.mercurial-scm.org/repo/hg
110
110
111 Mailing list: https://www.mercurial-scm.org/mailman/listinfo/mercurial/
111 Mailing list: https://www.mercurial-scm.org/mailman/listinfo/mercurial/
112
112
113 Copying
113 Copying
114 """""""
114 """""""
115 Copyright (C) 2005-2016 Matt Mackall.
115 Copyright (C) 2005-2017 Matt Mackall.
116 Free use of this software is granted under the terms of the GNU General
116 Free use of this software is granted under the terms of the GNU General
117 Public License version 2 or any later version.
117 Public License version 2 or any later version.
118
118
119 .. include:: common.txt
119 .. include:: common.txt
@@ -1,34 +1,34 b''
1 ==========
1 ==========
2 hgignore
2 hgignore
3 ==========
3 ==========
4
4
5 ---------------------------------
5 ---------------------------------
6 syntax for Mercurial ignore files
6 syntax for Mercurial ignore files
7 ---------------------------------
7 ---------------------------------
8
8
9 :Author: Vadim Gelfer <vadim.gelfer@gmail.com>
9 :Author: Vadim Gelfer <vadim.gelfer@gmail.com>
10 :Organization: Mercurial
10 :Organization: Mercurial
11 :Manual section: 5
11 :Manual section: 5
12 :Manual group: Mercurial Manual
12 :Manual group: Mercurial Manual
13
13
14 .. include:: hgignore.5.gendoc.txt
14 .. include:: hgignore.5.gendoc.txt
15
15
16 Author
16 Author
17 ======
17 ======
18 Vadim Gelfer <vadim.gelfer@gmail.com>
18 Vadim Gelfer <vadim.gelfer@gmail.com>
19
19
20 Mercurial was written by Matt Mackall <mpm@selenic.com>.
20 Mercurial was written by Matt Mackall <mpm@selenic.com>.
21
21
22 See Also
22 See Also
23 ========
23 ========
24 |hg(1)|_, |hgrc(5)|_
24 |hg(1)|_, |hgrc(5)|_
25
25
26 Copying
26 Copying
27 =======
27 =======
28 This manual page is copyright 2006 Vadim Gelfer.
28 This manual page is copyright 2006 Vadim Gelfer.
29 Mercurial is copyright 2005-2016 Matt Mackall.
29 Mercurial is copyright 2005-2017 Matt Mackall.
30 Free use of this software is granted under the terms of the GNU General
30 Free use of this software is granted under the terms of the GNU General
31 Public License version 2 or any later version.
31 Public License version 2 or any later version.
32
32
33 .. include:: common.txt
33 .. include:: common.txt
34
34
@@ -1,41 +1,41 b''
1 ======
1 ======
2 hgrc
2 hgrc
3 ======
3 ======
4
4
5 ---------------------------------
5 ---------------------------------
6 configuration files for Mercurial
6 configuration files for Mercurial
7 ---------------------------------
7 ---------------------------------
8
8
9 :Author: Bryan O'Sullivan <bos@serpentine.com>
9 :Author: Bryan O'Sullivan <bos@serpentine.com>
10 :Organization: Mercurial
10 :Organization: Mercurial
11 :Manual section: 5
11 :Manual section: 5
12 :Manual group: Mercurial Manual
12 :Manual group: Mercurial Manual
13
13
14 .. contents::
14 .. contents::
15 :backlinks: top
15 :backlinks: top
16 :class: htmlonly
16 :class: htmlonly
17
17
18
18
19 Description
19 Description
20 ===========
20 ===========
21
21
22 .. include:: hgrc.5.gendoc.txt
22 .. include:: hgrc.5.gendoc.txt
23
23
24 Author
24 Author
25 ======
25 ======
26 Bryan O'Sullivan <bos@serpentine.com>.
26 Bryan O'Sullivan <bos@serpentine.com>.
27
27
28 Mercurial was written by Matt Mackall <mpm@selenic.com>.
28 Mercurial was written by Matt Mackall <mpm@selenic.com>.
29
29
30 See Also
30 See Also
31 ========
31 ========
32 |hg(1)|_, |hgignore(5)|_
32 |hg(1)|_, |hgignore(5)|_
33
33
34 Copying
34 Copying
35 =======
35 =======
36 This manual page is copyright 2005 Bryan O'Sullivan.
36 This manual page is copyright 2005 Bryan O'Sullivan.
37 Mercurial is copyright 2005-2016 Matt Mackall.
37 Mercurial is copyright 2005-2017 Matt Mackall.
38 Free use of this software is granted under the terms of the GNU General
38 Free use of this software is granted under the terms of the GNU General
39 Public License version 2 or any later version.
39 Public License version 2 or any later version.
40
40
41 .. include:: common.txt
41 .. include:: common.txt
@@ -1,758 +1,758 b''
1 #
1 #
2 # This is the mercurial setup script.
2 # This is the mercurial setup script.
3 #
3 #
4 # 'python setup.py install', or
4 # 'python setup.py install', or
5 # 'python setup.py --help' for more options
5 # 'python setup.py --help' for more options
6
6
7 import sys, platform
7 import sys, platform
8 if getattr(sys, 'version_info', (0, 0, 0)) < (2, 6, 0, 'final'):
8 if getattr(sys, 'version_info', (0, 0, 0)) < (2, 6, 0, 'final'):
9 raise SystemExit("Mercurial requires Python 2.6 or later.")
9 raise SystemExit("Mercurial requires Python 2.6 or later.")
10
10
11 if sys.version_info[0] >= 3:
11 if sys.version_info[0] >= 3:
12 printf = eval('print')
12 printf = eval('print')
13 libdir_escape = 'unicode_escape'
13 libdir_escape = 'unicode_escape'
14 else:
14 else:
15 libdir_escape = 'string_escape'
15 libdir_escape = 'string_escape'
16 def printf(*args, **kwargs):
16 def printf(*args, **kwargs):
17 f = kwargs.get('file', sys.stdout)
17 f = kwargs.get('file', sys.stdout)
18 end = kwargs.get('end', '\n')
18 end = kwargs.get('end', '\n')
19 f.write(b' '.join(args) + end)
19 f.write(b' '.join(args) + end)
20
20
21 # Solaris Python packaging brain damage
21 # Solaris Python packaging brain damage
22 try:
22 try:
23 import hashlib
23 import hashlib
24 sha = hashlib.sha1()
24 sha = hashlib.sha1()
25 except ImportError:
25 except ImportError:
26 try:
26 try:
27 import sha
27 import sha
28 sha.sha # silence unused import warning
28 sha.sha # silence unused import warning
29 except ImportError:
29 except ImportError:
30 raise SystemExit(
30 raise SystemExit(
31 "Couldn't import standard hashlib (incomplete Python install).")
31 "Couldn't import standard hashlib (incomplete Python install).")
32
32
33 try:
33 try:
34 import zlib
34 import zlib
35 zlib.compressobj # silence unused import warning
35 zlib.compressobj # silence unused import warning
36 except ImportError:
36 except ImportError:
37 raise SystemExit(
37 raise SystemExit(
38 "Couldn't import standard zlib (incomplete Python install).")
38 "Couldn't import standard zlib (incomplete Python install).")
39
39
40 # The base IronPython distribution (as of 2.7.1) doesn't support bz2
40 # The base IronPython distribution (as of 2.7.1) doesn't support bz2
41 isironpython = False
41 isironpython = False
42 try:
42 try:
43 isironpython = (platform.python_implementation()
43 isironpython = (platform.python_implementation()
44 .lower().find("ironpython") != -1)
44 .lower().find("ironpython") != -1)
45 except AttributeError:
45 except AttributeError:
46 pass
46 pass
47
47
48 if isironpython:
48 if isironpython:
49 sys.stderr.write("warning: IronPython detected (no bz2 support)\n")
49 sys.stderr.write("warning: IronPython detected (no bz2 support)\n")
50 else:
50 else:
51 try:
51 try:
52 import bz2
52 import bz2
53 bz2.BZ2Compressor # silence unused import warning
53 bz2.BZ2Compressor # silence unused import warning
54 except ImportError:
54 except ImportError:
55 raise SystemExit(
55 raise SystemExit(
56 "Couldn't import standard bz2 (incomplete Python install).")
56 "Couldn't import standard bz2 (incomplete Python install).")
57
57
58 ispypy = "PyPy" in sys.version
58 ispypy = "PyPy" in sys.version
59
59
60 import ctypes
60 import ctypes
61 import os, stat, subprocess, time
61 import os, stat, subprocess, time
62 import re
62 import re
63 import shutil
63 import shutil
64 import tempfile
64 import tempfile
65 from distutils import log
65 from distutils import log
66 if 'FORCE_SETUPTOOLS' in os.environ:
66 if 'FORCE_SETUPTOOLS' in os.environ:
67 from setuptools import setup
67 from setuptools import setup
68 else:
68 else:
69 from distutils.core import setup
69 from distutils.core import setup
70 from distutils.ccompiler import new_compiler
70 from distutils.ccompiler import new_compiler
71 from distutils.core import Command, Extension
71 from distutils.core import Command, Extension
72 from distutils.dist import Distribution
72 from distutils.dist import Distribution
73 from distutils.command.build import build
73 from distutils.command.build import build
74 from distutils.command.build_ext import build_ext
74 from distutils.command.build_ext import build_ext
75 from distutils.command.build_py import build_py
75 from distutils.command.build_py import build_py
76 from distutils.command.build_scripts import build_scripts
76 from distutils.command.build_scripts import build_scripts
77 from distutils.command.install_lib import install_lib
77 from distutils.command.install_lib import install_lib
78 from distutils.command.install_scripts import install_scripts
78 from distutils.command.install_scripts import install_scripts
79 from distutils.spawn import spawn, find_executable
79 from distutils.spawn import spawn, find_executable
80 from distutils import file_util
80 from distutils import file_util
81 from distutils.errors import (
81 from distutils.errors import (
82 CCompilerError,
82 CCompilerError,
83 DistutilsError,
83 DistutilsError,
84 DistutilsExecError,
84 DistutilsExecError,
85 )
85 )
86 from distutils.sysconfig import get_python_inc, get_config_var
86 from distutils.sysconfig import get_python_inc, get_config_var
87 from distutils.version import StrictVersion
87 from distutils.version import StrictVersion
88
88
89 scripts = ['hg']
89 scripts = ['hg']
90 if os.name == 'nt':
90 if os.name == 'nt':
91 # We remove hg.bat if we are able to build hg.exe.
91 # We remove hg.bat if we are able to build hg.exe.
92 scripts.append('contrib/win32/hg.bat')
92 scripts.append('contrib/win32/hg.bat')
93
93
94 # simplified version of distutils.ccompiler.CCompiler.has_function
94 # simplified version of distutils.ccompiler.CCompiler.has_function
95 # that actually removes its temporary files.
95 # that actually removes its temporary files.
96 def hasfunction(cc, funcname):
96 def hasfunction(cc, funcname):
97 tmpdir = tempfile.mkdtemp(prefix='hg-install-')
97 tmpdir = tempfile.mkdtemp(prefix='hg-install-')
98 devnull = oldstderr = None
98 devnull = oldstderr = None
99 try:
99 try:
100 fname = os.path.join(tmpdir, 'funcname.c')
100 fname = os.path.join(tmpdir, 'funcname.c')
101 f = open(fname, 'w')
101 f = open(fname, 'w')
102 f.write('int main(void) {\n')
102 f.write('int main(void) {\n')
103 f.write(' %s();\n' % funcname)
103 f.write(' %s();\n' % funcname)
104 f.write('}\n')
104 f.write('}\n')
105 f.close()
105 f.close()
106 # Redirect stderr to /dev/null to hide any error messages
106 # Redirect stderr to /dev/null to hide any error messages
107 # from the compiler.
107 # from the compiler.
108 # This will have to be changed if we ever have to check
108 # This will have to be changed if we ever have to check
109 # for a function on Windows.
109 # for a function on Windows.
110 devnull = open('/dev/null', 'w')
110 devnull = open('/dev/null', 'w')
111 oldstderr = os.dup(sys.stderr.fileno())
111 oldstderr = os.dup(sys.stderr.fileno())
112 os.dup2(devnull.fileno(), sys.stderr.fileno())
112 os.dup2(devnull.fileno(), sys.stderr.fileno())
113 objects = cc.compile([fname], output_dir=tmpdir)
113 objects = cc.compile([fname], output_dir=tmpdir)
114 cc.link_executable(objects, os.path.join(tmpdir, "a.out"))
114 cc.link_executable(objects, os.path.join(tmpdir, "a.out"))
115 return True
115 return True
116 except Exception:
116 except Exception:
117 return False
117 return False
118 finally:
118 finally:
119 if oldstderr is not None:
119 if oldstderr is not None:
120 os.dup2(oldstderr, sys.stderr.fileno())
120 os.dup2(oldstderr, sys.stderr.fileno())
121 if devnull is not None:
121 if devnull is not None:
122 devnull.close()
122 devnull.close()
123 shutil.rmtree(tmpdir)
123 shutil.rmtree(tmpdir)
124
124
125 # py2exe needs to be installed to work
125 # py2exe needs to be installed to work
126 try:
126 try:
127 import py2exe
127 import py2exe
128 py2exe.Distribution # silence unused import warning
128 py2exe.Distribution # silence unused import warning
129 py2exeloaded = True
129 py2exeloaded = True
130 # import py2exe's patched Distribution class
130 # import py2exe's patched Distribution class
131 from distutils.core import Distribution
131 from distutils.core import Distribution
132 except ImportError:
132 except ImportError:
133 py2exeloaded = False
133 py2exeloaded = False
134
134
135 def runcmd(cmd, env):
135 def runcmd(cmd, env):
136 if (sys.platform == 'plan9'
136 if (sys.platform == 'plan9'
137 and (sys.version_info[0] == 2 and sys.version_info[1] < 7)):
137 and (sys.version_info[0] == 2 and sys.version_info[1] < 7)):
138 # subprocess kludge to work around issues in half-baked Python
138 # subprocess kludge to work around issues in half-baked Python
139 # ports, notably bichued/python:
139 # ports, notably bichued/python:
140 _, out, err = os.popen3(cmd)
140 _, out, err = os.popen3(cmd)
141 return str(out), str(err)
141 return str(out), str(err)
142 else:
142 else:
143 p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
143 p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
144 stderr=subprocess.PIPE, env=env)
144 stderr=subprocess.PIPE, env=env)
145 out, err = p.communicate()
145 out, err = p.communicate()
146 return out, err
146 return out, err
147
147
148 def runhg(cmd, env):
148 def runhg(cmd, env):
149 out, err = runcmd(cmd, env)
149 out, err = runcmd(cmd, env)
150 # If root is executing setup.py, but the repository is owned by
150 # If root is executing setup.py, but the repository is owned by
151 # another user (as in "sudo python setup.py install") we will get
151 # another user (as in "sudo python setup.py install") we will get
152 # trust warnings since the .hg/hgrc file is untrusted. That is
152 # trust warnings since the .hg/hgrc file is untrusted. That is
153 # fine, we don't want to load it anyway. Python may warn about
153 # fine, we don't want to load it anyway. Python may warn about
154 # a missing __init__.py in mercurial/locale, we also ignore that.
154 # a missing __init__.py in mercurial/locale, we also ignore that.
155 err = [e for e in err.splitlines()
155 err = [e for e in err.splitlines()
156 if not e.startswith(b'not trusting file') \
156 if not e.startswith(b'not trusting file') \
157 and not e.startswith(b'warning: Not importing') \
157 and not e.startswith(b'warning: Not importing') \
158 and not e.startswith(b'obsolete feature not enabled')]
158 and not e.startswith(b'obsolete feature not enabled')]
159 if err:
159 if err:
160 printf("stderr from '%s':" % (' '.join(cmd)), file=sys.stderr)
160 printf("stderr from '%s':" % (' '.join(cmd)), file=sys.stderr)
161 printf(b'\n'.join([b' ' + e for e in err]), file=sys.stderr)
161 printf(b'\n'.join([b' ' + e for e in err]), file=sys.stderr)
162 return ''
162 return ''
163 return out
163 return out
164
164
165 version = ''
165 version = ''
166
166
167 # Execute hg out of this directory with a custom environment which takes care
167 # Execute hg out of this directory with a custom environment which takes care
168 # to not use any hgrc files and do no localization.
168 # to not use any hgrc files and do no localization.
169 env = {'HGMODULEPOLICY': 'py',
169 env = {'HGMODULEPOLICY': 'py',
170 'HGRCPATH': '',
170 'HGRCPATH': '',
171 'LANGUAGE': 'C',
171 'LANGUAGE': 'C',
172 'PATH': ''} # make pypi modules that use os.environ['PATH'] happy
172 'PATH': ''} # make pypi modules that use os.environ['PATH'] happy
173 if 'LD_LIBRARY_PATH' in os.environ:
173 if 'LD_LIBRARY_PATH' in os.environ:
174 env['LD_LIBRARY_PATH'] = os.environ['LD_LIBRARY_PATH']
174 env['LD_LIBRARY_PATH'] = os.environ['LD_LIBRARY_PATH']
175 if 'SystemRoot' in os.environ:
175 if 'SystemRoot' in os.environ:
176 # Copy SystemRoot into the custom environment for Python 2.6
176 # Copy SystemRoot into the custom environment for Python 2.6
177 # under Windows. Otherwise, the subprocess will fail with
177 # under Windows. Otherwise, the subprocess will fail with
178 # error 0xc0150004. See: http://bugs.python.org/issue3440
178 # error 0xc0150004. See: http://bugs.python.org/issue3440
179 env['SystemRoot'] = os.environ['SystemRoot']
179 env['SystemRoot'] = os.environ['SystemRoot']
180
180
181 if os.path.isdir('.hg'):
181 if os.path.isdir('.hg'):
182 cmd = [sys.executable, 'hg', 'log', '-r', '.', '--template', '{tags}\n']
182 cmd = [sys.executable, 'hg', 'log', '-r', '.', '--template', '{tags}\n']
183 numerictags = [t for t in runhg(cmd, env).split() if t[0].isdigit()]
183 numerictags = [t for t in runhg(cmd, env).split() if t[0].isdigit()]
184 hgid = runhg([sys.executable, 'hg', 'id', '-i'], env).strip()
184 hgid = runhg([sys.executable, 'hg', 'id', '-i'], env).strip()
185 if numerictags: # tag(s) found
185 if numerictags: # tag(s) found
186 version = numerictags[-1]
186 version = numerictags[-1]
187 if hgid.endswith('+'): # propagate the dirty status to the tag
187 if hgid.endswith('+'): # propagate the dirty status to the tag
188 version += '+'
188 version += '+'
189 else: # no tag found
189 else: # no tag found
190 ltagcmd = [sys.executable, 'hg', 'parents', '--template',
190 ltagcmd = [sys.executable, 'hg', 'parents', '--template',
191 '{latesttag}']
191 '{latesttag}']
192 ltag = runhg(ltagcmd, env)
192 ltag = runhg(ltagcmd, env)
193 changessincecmd = [sys.executable, 'hg', 'log', '-T', 'x\n', '-r',
193 changessincecmd = [sys.executable, 'hg', 'log', '-T', 'x\n', '-r',
194 "only(.,'%s')" % ltag]
194 "only(.,'%s')" % ltag]
195 changessince = len(runhg(changessincecmd, env).splitlines())
195 changessince = len(runhg(changessincecmd, env).splitlines())
196 version = '%s+%s-%s' % (ltag, changessince, hgid)
196 version = '%s+%s-%s' % (ltag, changessince, hgid)
197 if version.endswith('+'):
197 if version.endswith('+'):
198 version += time.strftime('%Y%m%d')
198 version += time.strftime('%Y%m%d')
199 elif os.path.exists('.hg_archival.txt'):
199 elif os.path.exists('.hg_archival.txt'):
200 kw = dict([[t.strip() for t in l.split(':', 1)]
200 kw = dict([[t.strip() for t in l.split(':', 1)]
201 for l in open('.hg_archival.txt')])
201 for l in open('.hg_archival.txt')])
202 if 'tag' in kw:
202 if 'tag' in kw:
203 version = kw['tag']
203 version = kw['tag']
204 elif 'latesttag' in kw:
204 elif 'latesttag' in kw:
205 if 'changessincelatesttag' in kw:
205 if 'changessincelatesttag' in kw:
206 version = '%(latesttag)s+%(changessincelatesttag)s-%(node).12s' % kw
206 version = '%(latesttag)s+%(changessincelatesttag)s-%(node).12s' % kw
207 else:
207 else:
208 version = '%(latesttag)s+%(latesttagdistance)s-%(node).12s' % kw
208 version = '%(latesttag)s+%(latesttagdistance)s-%(node).12s' % kw
209 else:
209 else:
210 version = kw.get('node', '')[:12]
210 version = kw.get('node', '')[:12]
211
211
212 if version:
212 if version:
213 with open("mercurial/__version__.py", "w") as f:
213 with open("mercurial/__version__.py", "w") as f:
214 f.write('# this file is autogenerated by setup.py\n')
214 f.write('# this file is autogenerated by setup.py\n')
215 f.write('version = "%s"\n' % version)
215 f.write('version = "%s"\n' % version)
216
216
217 try:
217 try:
218 oldpolicy = os.environ.get('HGMODULEPOLICY', None)
218 oldpolicy = os.environ.get('HGMODULEPOLICY', None)
219 os.environ['HGMODULEPOLICY'] = 'py'
219 os.environ['HGMODULEPOLICY'] = 'py'
220 from mercurial import __version__
220 from mercurial import __version__
221 version = __version__.version
221 version = __version__.version
222 except ImportError:
222 except ImportError:
223 version = 'unknown'
223 version = 'unknown'
224 finally:
224 finally:
225 if oldpolicy is None:
225 if oldpolicy is None:
226 del os.environ['HGMODULEPOLICY']
226 del os.environ['HGMODULEPOLICY']
227 else:
227 else:
228 os.environ['HGMODULEPOLICY'] = oldpolicy
228 os.environ['HGMODULEPOLICY'] = oldpolicy
229
229
230 class hgbuild(build):
230 class hgbuild(build):
231 # Insert hgbuildmo first so that files in mercurial/locale/ are found
231 # Insert hgbuildmo first so that files in mercurial/locale/ are found
232 # when build_py is run next.
232 # when build_py is run next.
233 sub_commands = [('build_mo', None)] + build.sub_commands
233 sub_commands = [('build_mo', None)] + build.sub_commands
234
234
235 class hgbuildmo(build):
235 class hgbuildmo(build):
236
236
237 description = "build translations (.mo files)"
237 description = "build translations (.mo files)"
238
238
239 def run(self):
239 def run(self):
240 if not find_executable('msgfmt'):
240 if not find_executable('msgfmt'):
241 self.warn("could not find msgfmt executable, no translations "
241 self.warn("could not find msgfmt executable, no translations "
242 "will be built")
242 "will be built")
243 return
243 return
244
244
245 podir = 'i18n'
245 podir = 'i18n'
246 if not os.path.isdir(podir):
246 if not os.path.isdir(podir):
247 self.warn("could not find %s/ directory" % podir)
247 self.warn("could not find %s/ directory" % podir)
248 return
248 return
249
249
250 join = os.path.join
250 join = os.path.join
251 for po in os.listdir(podir):
251 for po in os.listdir(podir):
252 if not po.endswith('.po'):
252 if not po.endswith('.po'):
253 continue
253 continue
254 pofile = join(podir, po)
254 pofile = join(podir, po)
255 modir = join('locale', po[:-3], 'LC_MESSAGES')
255 modir = join('locale', po[:-3], 'LC_MESSAGES')
256 mofile = join(modir, 'hg.mo')
256 mofile = join(modir, 'hg.mo')
257 mobuildfile = join('mercurial', mofile)
257 mobuildfile = join('mercurial', mofile)
258 cmd = ['msgfmt', '-v', '-o', mobuildfile, pofile]
258 cmd = ['msgfmt', '-v', '-o', mobuildfile, pofile]
259 if sys.platform != 'sunos5':
259 if sys.platform != 'sunos5':
260 # msgfmt on Solaris does not know about -c
260 # msgfmt on Solaris does not know about -c
261 cmd.append('-c')
261 cmd.append('-c')
262 self.mkpath(join('mercurial', modir))
262 self.mkpath(join('mercurial', modir))
263 self.make_file([pofile], mobuildfile, spawn, (cmd,))
263 self.make_file([pofile], mobuildfile, spawn, (cmd,))
264
264
265
265
266 class hgdist(Distribution):
266 class hgdist(Distribution):
267 pure = False
267 pure = False
268 cffi = ispypy
268 cffi = ispypy
269
269
270 global_options = Distribution.global_options + \
270 global_options = Distribution.global_options + \
271 [('pure', None, "use pure (slow) Python "
271 [('pure', None, "use pure (slow) Python "
272 "code instead of C extensions"),
272 "code instead of C extensions"),
273 ]
273 ]
274
274
275 def has_ext_modules(self):
275 def has_ext_modules(self):
276 # self.ext_modules is emptied in hgbuildpy.finalize_options which is
276 # self.ext_modules is emptied in hgbuildpy.finalize_options which is
277 # too late for some cases
277 # too late for some cases
278 return not self.pure and Distribution.has_ext_modules(self)
278 return not self.pure and Distribution.has_ext_modules(self)
279
279
280 # This is ugly as a one-liner. So use a variable.
280 # This is ugly as a one-liner. So use a variable.
281 buildextnegops = dict(getattr(build_ext, 'negative_options', {}))
281 buildextnegops = dict(getattr(build_ext, 'negative_options', {}))
282 buildextnegops['no-zstd'] = 'zstd'
282 buildextnegops['no-zstd'] = 'zstd'
283
283
284 class hgbuildext(build_ext):
284 class hgbuildext(build_ext):
285 user_options = build_ext.user_options + [
285 user_options = build_ext.user_options + [
286 ('zstd', None, 'compile zstd bindings [default]'),
286 ('zstd', None, 'compile zstd bindings [default]'),
287 ('no-zstd', None, 'do not compile zstd bindings'),
287 ('no-zstd', None, 'do not compile zstd bindings'),
288 ]
288 ]
289
289
290 boolean_options = build_ext.boolean_options + ['zstd']
290 boolean_options = build_ext.boolean_options + ['zstd']
291 negative_opt = buildextnegops
291 negative_opt = buildextnegops
292
292
293 def initialize_options(self):
293 def initialize_options(self):
294 self.zstd = True
294 self.zstd = True
295 return build_ext.initialize_options(self)
295 return build_ext.initialize_options(self)
296
296
297 def build_extensions(self):
297 def build_extensions(self):
298 # Filter out zstd if disabled via argument.
298 # Filter out zstd if disabled via argument.
299 if not self.zstd:
299 if not self.zstd:
300 self.extensions = [e for e in self.extensions
300 self.extensions = [e for e in self.extensions
301 if e.name != 'mercurial.zstd']
301 if e.name != 'mercurial.zstd']
302
302
303 return build_ext.build_extensions(self)
303 return build_ext.build_extensions(self)
304
304
305 def build_extension(self, ext):
305 def build_extension(self, ext):
306 try:
306 try:
307 build_ext.build_extension(self, ext)
307 build_ext.build_extension(self, ext)
308 except CCompilerError:
308 except CCompilerError:
309 if not getattr(ext, 'optional', False):
309 if not getattr(ext, 'optional', False):
310 raise
310 raise
311 log.warn("Failed to build optional extension '%s' (skipping)",
311 log.warn("Failed to build optional extension '%s' (skipping)",
312 ext.name)
312 ext.name)
313
313
314 class hgbuildscripts(build_scripts):
314 class hgbuildscripts(build_scripts):
315 def run(self):
315 def run(self):
316 if os.name != 'nt' or self.distribution.pure:
316 if os.name != 'nt' or self.distribution.pure:
317 return build_scripts.run(self)
317 return build_scripts.run(self)
318
318
319 exebuilt = False
319 exebuilt = False
320 try:
320 try:
321 self.run_command('build_hgexe')
321 self.run_command('build_hgexe')
322 exebuilt = True
322 exebuilt = True
323 except (DistutilsError, CCompilerError):
323 except (DistutilsError, CCompilerError):
324 log.warn('failed to build optional hg.exe')
324 log.warn('failed to build optional hg.exe')
325
325
326 if exebuilt:
326 if exebuilt:
327 # Copying hg.exe to the scripts build directory ensures it is
327 # Copying hg.exe to the scripts build directory ensures it is
328 # installed by the install_scripts command.
328 # installed by the install_scripts command.
329 hgexecommand = self.get_finalized_command('build_hgexe')
329 hgexecommand = self.get_finalized_command('build_hgexe')
330 dest = os.path.join(self.build_dir, 'hg.exe')
330 dest = os.path.join(self.build_dir, 'hg.exe')
331 self.mkpath(self.build_dir)
331 self.mkpath(self.build_dir)
332 self.copy_file(hgexecommand.hgexepath, dest)
332 self.copy_file(hgexecommand.hgexepath, dest)
333
333
334 # Remove hg.bat because it is redundant with hg.exe.
334 # Remove hg.bat because it is redundant with hg.exe.
335 self.scripts.remove('contrib/win32/hg.bat')
335 self.scripts.remove('contrib/win32/hg.bat')
336
336
337 return build_scripts.run(self)
337 return build_scripts.run(self)
338
338
339 class hgbuildpy(build_py):
339 class hgbuildpy(build_py):
340 def finalize_options(self):
340 def finalize_options(self):
341 build_py.finalize_options(self)
341 build_py.finalize_options(self)
342
342
343 if self.distribution.pure:
343 if self.distribution.pure:
344 self.distribution.ext_modules = []
344 self.distribution.ext_modules = []
345 elif self.distribution.cffi:
345 elif self.distribution.cffi:
346 from mercurial.cffi import (
346 from mercurial.cffi import (
347 bdiff,
347 bdiff,
348 mpatch,
348 mpatch,
349 )
349 )
350 exts = [mpatch.ffi.distutils_extension(),
350 exts = [mpatch.ffi.distutils_extension(),
351 bdiff.ffi.distutils_extension()]
351 bdiff.ffi.distutils_extension()]
352 # cffi modules go here
352 # cffi modules go here
353 if sys.platform == 'darwin':
353 if sys.platform == 'darwin':
354 from mercurial.cffi import osutil
354 from mercurial.cffi import osutil
355 exts.append(osutil.ffi.distutils_extension())
355 exts.append(osutil.ffi.distutils_extension())
356 self.distribution.ext_modules = exts
356 self.distribution.ext_modules = exts
357 else:
357 else:
358 h = os.path.join(get_python_inc(), 'Python.h')
358 h = os.path.join(get_python_inc(), 'Python.h')
359 if not os.path.exists(h):
359 if not os.path.exists(h):
360 raise SystemExit('Python headers are required to build '
360 raise SystemExit('Python headers are required to build '
361 'Mercurial but weren\'t found in %s' % h)
361 'Mercurial but weren\'t found in %s' % h)
362
362
363 def run(self):
363 def run(self):
364 if self.distribution.pure:
364 if self.distribution.pure:
365 modulepolicy = 'py'
365 modulepolicy = 'py'
366 else:
366 else:
367 modulepolicy = 'c'
367 modulepolicy = 'c'
368 with open("mercurial/__modulepolicy__.py", "w") as f:
368 with open("mercurial/__modulepolicy__.py", "w") as f:
369 f.write('# this file is autogenerated by setup.py\n')
369 f.write('# this file is autogenerated by setup.py\n')
370 f.write('modulepolicy = "%s"\n' % modulepolicy)
370 f.write('modulepolicy = "%s"\n' % modulepolicy)
371
371
372 build_py.run(self)
372 build_py.run(self)
373
373
374 class buildhgextindex(Command):
374 class buildhgextindex(Command):
375 description = 'generate prebuilt index of hgext (for frozen package)'
375 description = 'generate prebuilt index of hgext (for frozen package)'
376 user_options = []
376 user_options = []
377 _indexfilename = 'hgext/__index__.py'
377 _indexfilename = 'hgext/__index__.py'
378
378
379 def initialize_options(self):
379 def initialize_options(self):
380 pass
380 pass
381
381
382 def finalize_options(self):
382 def finalize_options(self):
383 pass
383 pass
384
384
385 def run(self):
385 def run(self):
386 if os.path.exists(self._indexfilename):
386 if os.path.exists(self._indexfilename):
387 with open(self._indexfilename, 'w') as f:
387 with open(self._indexfilename, 'w') as f:
388 f.write('# empty\n')
388 f.write('# empty\n')
389
389
390 # here no extension enabled, disabled() lists up everything
390 # here no extension enabled, disabled() lists up everything
391 code = ('import pprint; from mercurial import extensions; '
391 code = ('import pprint; from mercurial import extensions; '
392 'pprint.pprint(extensions.disabled())')
392 'pprint.pprint(extensions.disabled())')
393 out, err = runcmd([sys.executable, '-c', code], env)
393 out, err = runcmd([sys.executable, '-c', code], env)
394 if err:
394 if err:
395 raise DistutilsExecError(err)
395 raise DistutilsExecError(err)
396
396
397 with open(self._indexfilename, 'w') as f:
397 with open(self._indexfilename, 'w') as f:
398 f.write('# this file is autogenerated by setup.py\n')
398 f.write('# this file is autogenerated by setup.py\n')
399 f.write('docs = ')
399 f.write('docs = ')
400 f.write(out)
400 f.write(out)
401
401
402 class buildhgexe(build_ext):
402 class buildhgexe(build_ext):
403 description = 'compile hg.exe from mercurial/exewrapper.c'
403 description = 'compile hg.exe from mercurial/exewrapper.c'
404
404
405 def build_extensions(self):
405 def build_extensions(self):
406 if os.name != 'nt':
406 if os.name != 'nt':
407 return
407 return
408 if isinstance(self.compiler, HackedMingw32CCompiler):
408 if isinstance(self.compiler, HackedMingw32CCompiler):
409 self.compiler.compiler_so = self.compiler.compiler # no -mdll
409 self.compiler.compiler_so = self.compiler.compiler # no -mdll
410 self.compiler.dll_libraries = [] # no -lmsrvc90
410 self.compiler.dll_libraries = [] # no -lmsrvc90
411
411
412 # Different Python installs can have different Python library
412 # Different Python installs can have different Python library
413 # names. e.g. the official CPython distribution uses pythonXY.dll
413 # names. e.g. the official CPython distribution uses pythonXY.dll
414 # and MinGW uses libpythonX.Y.dll.
414 # and MinGW uses libpythonX.Y.dll.
415 _kernel32 = ctypes.windll.kernel32
415 _kernel32 = ctypes.windll.kernel32
416 _kernel32.GetModuleFileNameA.argtypes = [ctypes.c_void_p,
416 _kernel32.GetModuleFileNameA.argtypes = [ctypes.c_void_p,
417 ctypes.c_void_p,
417 ctypes.c_void_p,
418 ctypes.c_ulong]
418 ctypes.c_ulong]
419 _kernel32.GetModuleFileNameA.restype = ctypes.c_ulong
419 _kernel32.GetModuleFileNameA.restype = ctypes.c_ulong
420 size = 1000
420 size = 1000
421 buf = ctypes.create_string_buffer(size + 1)
421 buf = ctypes.create_string_buffer(size + 1)
422 filelen = _kernel32.GetModuleFileNameA(sys.dllhandle, ctypes.byref(buf),
422 filelen = _kernel32.GetModuleFileNameA(sys.dllhandle, ctypes.byref(buf),
423 size)
423 size)
424
424
425 if filelen > 0 and filelen != size:
425 if filelen > 0 and filelen != size:
426 dllbasename = os.path.basename(buf.value)
426 dllbasename = os.path.basename(buf.value)
427 if not dllbasename.lower().endswith('.dll'):
427 if not dllbasename.lower().endswith('.dll'):
428 raise SystemExit('Python DLL does not end with .dll: %s' %
428 raise SystemExit('Python DLL does not end with .dll: %s' %
429 dllbasename)
429 dllbasename)
430 pythonlib = dllbasename[:-4]
430 pythonlib = dllbasename[:-4]
431 else:
431 else:
432 log.warn('could not determine Python DLL filename; '
432 log.warn('could not determine Python DLL filename; '
433 'assuming pythonXY')
433 'assuming pythonXY')
434
434
435 hv = sys.hexversion
435 hv = sys.hexversion
436 pythonlib = 'python%d%d' % (hv >> 24, (hv >> 16) & 0xff)
436 pythonlib = 'python%d%d' % (hv >> 24, (hv >> 16) & 0xff)
437
437
438 log.info('using %s as Python library name' % pythonlib)
438 log.info('using %s as Python library name' % pythonlib)
439 with open('mercurial/hgpythonlib.h', 'wb') as f:
439 with open('mercurial/hgpythonlib.h', 'wb') as f:
440 f.write('/* this file is autogenerated by setup.py */\n')
440 f.write('/* this file is autogenerated by setup.py */\n')
441 f.write('#define HGPYTHONLIB "%s"\n' % pythonlib)
441 f.write('#define HGPYTHONLIB "%s"\n' % pythonlib)
442 objects = self.compiler.compile(['mercurial/exewrapper.c'],
442 objects = self.compiler.compile(['mercurial/exewrapper.c'],
443 output_dir=self.build_temp)
443 output_dir=self.build_temp)
444 dir = os.path.dirname(self.get_ext_fullpath('dummy'))
444 dir = os.path.dirname(self.get_ext_fullpath('dummy'))
445 target = os.path.join(dir, 'hg')
445 target = os.path.join(dir, 'hg')
446 self.compiler.link_executable(objects, target,
446 self.compiler.link_executable(objects, target,
447 libraries=[],
447 libraries=[],
448 output_dir=self.build_temp)
448 output_dir=self.build_temp)
449
449
450 @property
450 @property
451 def hgexepath(self):
451 def hgexepath(self):
452 dir = os.path.dirname(self.get_ext_fullpath('dummy'))
452 dir = os.path.dirname(self.get_ext_fullpath('dummy'))
453 return os.path.join(self.build_temp, dir, 'hg.exe')
453 return os.path.join(self.build_temp, dir, 'hg.exe')
454
454
455 class hginstalllib(install_lib):
455 class hginstalllib(install_lib):
456 '''
456 '''
457 This is a specialization of install_lib that replaces the copy_file used
457 This is a specialization of install_lib that replaces the copy_file used
458 there so that it supports setting the mode of files after copying them,
458 there so that it supports setting the mode of files after copying them,
459 instead of just preserving the mode that the files originally had. If your
459 instead of just preserving the mode that the files originally had. If your
460 system has a umask of something like 027, preserving the permissions when
460 system has a umask of something like 027, preserving the permissions when
461 copying will lead to a broken install.
461 copying will lead to a broken install.
462
462
463 Note that just passing keep_permissions=False to copy_file would be
463 Note that just passing keep_permissions=False to copy_file would be
464 insufficient, as it might still be applying a umask.
464 insufficient, as it might still be applying a umask.
465 '''
465 '''
466
466
467 def run(self):
467 def run(self):
468 realcopyfile = file_util.copy_file
468 realcopyfile = file_util.copy_file
469 def copyfileandsetmode(*args, **kwargs):
469 def copyfileandsetmode(*args, **kwargs):
470 src, dst = args[0], args[1]
470 src, dst = args[0], args[1]
471 dst, copied = realcopyfile(*args, **kwargs)
471 dst, copied = realcopyfile(*args, **kwargs)
472 if copied:
472 if copied:
473 st = os.stat(src)
473 st = os.stat(src)
474 # Persist executable bit (apply it to group and other if user
474 # Persist executable bit (apply it to group and other if user
475 # has it)
475 # has it)
476 if st[stat.ST_MODE] & stat.S_IXUSR:
476 if st[stat.ST_MODE] & stat.S_IXUSR:
477 setmode = int('0755', 8)
477 setmode = int('0755', 8)
478 else:
478 else:
479 setmode = int('0644', 8)
479 setmode = int('0644', 8)
480 m = stat.S_IMODE(st[stat.ST_MODE])
480 m = stat.S_IMODE(st[stat.ST_MODE])
481 m = (m & ~int('0777', 8)) | setmode
481 m = (m & ~int('0777', 8)) | setmode
482 os.chmod(dst, m)
482 os.chmod(dst, m)
483 file_util.copy_file = copyfileandsetmode
483 file_util.copy_file = copyfileandsetmode
484 try:
484 try:
485 install_lib.run(self)
485 install_lib.run(self)
486 finally:
486 finally:
487 file_util.copy_file = realcopyfile
487 file_util.copy_file = realcopyfile
488
488
489 class hginstallscripts(install_scripts):
489 class hginstallscripts(install_scripts):
490 '''
490 '''
491 This is a specialization of install_scripts that replaces the @LIBDIR@ with
491 This is a specialization of install_scripts that replaces the @LIBDIR@ with
492 the configured directory for modules. If possible, the path is made relative
492 the configured directory for modules. If possible, the path is made relative
493 to the directory for scripts.
493 to the directory for scripts.
494 '''
494 '''
495
495
496 def initialize_options(self):
496 def initialize_options(self):
497 install_scripts.initialize_options(self)
497 install_scripts.initialize_options(self)
498
498
499 self.install_lib = None
499 self.install_lib = None
500
500
501 def finalize_options(self):
501 def finalize_options(self):
502 install_scripts.finalize_options(self)
502 install_scripts.finalize_options(self)
503 self.set_undefined_options('install',
503 self.set_undefined_options('install',
504 ('install_lib', 'install_lib'))
504 ('install_lib', 'install_lib'))
505
505
506 def run(self):
506 def run(self):
507 install_scripts.run(self)
507 install_scripts.run(self)
508
508
509 # It only makes sense to replace @LIBDIR@ with the install path if
509 # It only makes sense to replace @LIBDIR@ with the install path if
510 # the install path is known. For wheels, the logic below calculates
510 # the install path is known. For wheels, the logic below calculates
511 # the libdir to be "../..". This is because the internal layout of a
511 # the libdir to be "../..". This is because the internal layout of a
512 # wheel archive looks like:
512 # wheel archive looks like:
513 #
513 #
514 # mercurial-3.6.1.data/scripts/hg
514 # mercurial-3.6.1.data/scripts/hg
515 # mercurial/__init__.py
515 # mercurial/__init__.py
516 #
516 #
517 # When installing wheels, the subdirectories of the "<pkg>.data"
517 # When installing wheels, the subdirectories of the "<pkg>.data"
518 # directory are translated to system local paths and files therein
518 # directory are translated to system local paths and files therein
519 # are copied in place. The mercurial/* files are installed into the
519 # are copied in place. The mercurial/* files are installed into the
520 # site-packages directory. However, the site-packages directory
520 # site-packages directory. However, the site-packages directory
521 # isn't known until wheel install time. This means we have no clue
521 # isn't known until wheel install time. This means we have no clue
522 # at wheel generation time what the installed site-packages directory
522 # at wheel generation time what the installed site-packages directory
523 # will be. And, wheels don't appear to provide the ability to register
523 # will be. And, wheels don't appear to provide the ability to register
524 # custom code to run during wheel installation. This all means that
524 # custom code to run during wheel installation. This all means that
525 # we can't reliably set the libdir in wheels: the default behavior
525 # we can't reliably set the libdir in wheels: the default behavior
526 # of looking in sys.path must do.
526 # of looking in sys.path must do.
527
527
528 if (os.path.splitdrive(self.install_dir)[0] !=
528 if (os.path.splitdrive(self.install_dir)[0] !=
529 os.path.splitdrive(self.install_lib)[0]):
529 os.path.splitdrive(self.install_lib)[0]):
530 # can't make relative paths from one drive to another, so use an
530 # can't make relative paths from one drive to another, so use an
531 # absolute path instead
531 # absolute path instead
532 libdir = self.install_lib
532 libdir = self.install_lib
533 else:
533 else:
534 common = os.path.commonprefix((self.install_dir, self.install_lib))
534 common = os.path.commonprefix((self.install_dir, self.install_lib))
535 rest = self.install_dir[len(common):]
535 rest = self.install_dir[len(common):]
536 uplevel = len([n for n in os.path.split(rest) if n])
536 uplevel = len([n for n in os.path.split(rest) if n])
537
537
538 libdir = uplevel * ('..' + os.sep) + self.install_lib[len(common):]
538 libdir = uplevel * ('..' + os.sep) + self.install_lib[len(common):]
539
539
540 for outfile in self.outfiles:
540 for outfile in self.outfiles:
541 with open(outfile, 'rb') as fp:
541 with open(outfile, 'rb') as fp:
542 data = fp.read()
542 data = fp.read()
543
543
544 # skip binary files
544 # skip binary files
545 if b'\0' in data:
545 if b'\0' in data:
546 continue
546 continue
547
547
548 # During local installs, the shebang will be rewritten to the final
548 # During local installs, the shebang will be rewritten to the final
549 # install path. During wheel packaging, the shebang has a special
549 # install path. During wheel packaging, the shebang has a special
550 # value.
550 # value.
551 if data.startswith(b'#!python'):
551 if data.startswith(b'#!python'):
552 log.info('not rewriting @LIBDIR@ in %s because install path '
552 log.info('not rewriting @LIBDIR@ in %s because install path '
553 'not known' % outfile)
553 'not known' % outfile)
554 continue
554 continue
555
555
556 data = data.replace(b'@LIBDIR@', libdir.encode(libdir_escape))
556 data = data.replace(b'@LIBDIR@', libdir.encode(libdir_escape))
557 with open(outfile, 'wb') as fp:
557 with open(outfile, 'wb') as fp:
558 fp.write(data)
558 fp.write(data)
559
559
560 cmdclass = {'build': hgbuild,
560 cmdclass = {'build': hgbuild,
561 'build_mo': hgbuildmo,
561 'build_mo': hgbuildmo,
562 'build_ext': hgbuildext,
562 'build_ext': hgbuildext,
563 'build_py': hgbuildpy,
563 'build_py': hgbuildpy,
564 'build_scripts': hgbuildscripts,
564 'build_scripts': hgbuildscripts,
565 'build_hgextindex': buildhgextindex,
565 'build_hgextindex': buildhgextindex,
566 'install_lib': hginstalllib,
566 'install_lib': hginstalllib,
567 'install_scripts': hginstallscripts,
567 'install_scripts': hginstallscripts,
568 'build_hgexe': buildhgexe,
568 'build_hgexe': buildhgexe,
569 }
569 }
570
570
571 packages = ['mercurial', 'mercurial.hgweb', 'mercurial.httpclient',
571 packages = ['mercurial', 'mercurial.hgweb', 'mercurial.httpclient',
572 'mercurial.pure',
572 'mercurial.pure',
573 'hgext', 'hgext.convert', 'hgext.fsmonitor',
573 'hgext', 'hgext.convert', 'hgext.fsmonitor',
574 'hgext.fsmonitor.pywatchman', 'hgext.highlight',
574 'hgext.fsmonitor.pywatchman', 'hgext.highlight',
575 'hgext.largefiles', 'hgext.zeroconf', 'hgext3rd']
575 'hgext.largefiles', 'hgext.zeroconf', 'hgext3rd']
576
576
577 common_depends = ['mercurial/bitmanipulation.h',
577 common_depends = ['mercurial/bitmanipulation.h',
578 'mercurial/compat.h',
578 'mercurial/compat.h',
579 'mercurial/util.h']
579 'mercurial/util.h']
580
580
581 osutil_cflags = []
581 osutil_cflags = []
582 osutil_ldflags = []
582 osutil_ldflags = []
583
583
584 # platform specific macros: HAVE_SETPROCTITLE
584 # platform specific macros: HAVE_SETPROCTITLE
585 for plat, func in [(re.compile('freebsd'), 'setproctitle')]:
585 for plat, func in [(re.compile('freebsd'), 'setproctitle')]:
586 if plat.search(sys.platform) and hasfunction(new_compiler(), func):
586 if plat.search(sys.platform) and hasfunction(new_compiler(), func):
587 osutil_cflags.append('-DHAVE_%s' % func.upper())
587 osutil_cflags.append('-DHAVE_%s' % func.upper())
588
588
589 if sys.platform == 'darwin':
589 if sys.platform == 'darwin':
590 osutil_ldflags += ['-framework', 'ApplicationServices']
590 osutil_ldflags += ['-framework', 'ApplicationServices']
591
591
592 extmodules = [
592 extmodules = [
593 Extension('mercurial.base85', ['mercurial/base85.c'],
593 Extension('mercurial.base85', ['mercurial/base85.c'],
594 depends=common_depends),
594 depends=common_depends),
595 Extension('mercurial.bdiff', ['mercurial/bdiff.c',
595 Extension('mercurial.bdiff', ['mercurial/bdiff.c',
596 'mercurial/bdiff_module.c'],
596 'mercurial/bdiff_module.c'],
597 depends=common_depends + ['mercurial/bdiff.h']),
597 depends=common_depends + ['mercurial/bdiff.h']),
598 Extension('mercurial.diffhelpers', ['mercurial/diffhelpers.c'],
598 Extension('mercurial.diffhelpers', ['mercurial/diffhelpers.c'],
599 depends=common_depends),
599 depends=common_depends),
600 Extension('mercurial.mpatch', ['mercurial/mpatch.c',
600 Extension('mercurial.mpatch', ['mercurial/mpatch.c',
601 'mercurial/mpatch_module.c'],
601 'mercurial/mpatch_module.c'],
602 depends=common_depends),
602 depends=common_depends),
603 Extension('mercurial.parsers', ['mercurial/dirs.c',
603 Extension('mercurial.parsers', ['mercurial/dirs.c',
604 'mercurial/manifest.c',
604 'mercurial/manifest.c',
605 'mercurial/parsers.c',
605 'mercurial/parsers.c',
606 'mercurial/pathencode.c'],
606 'mercurial/pathencode.c'],
607 depends=common_depends),
607 depends=common_depends),
608 Extension('mercurial.osutil', ['mercurial/osutil.c'],
608 Extension('mercurial.osutil', ['mercurial/osutil.c'],
609 extra_compile_args=osutil_cflags,
609 extra_compile_args=osutil_cflags,
610 extra_link_args=osutil_ldflags,
610 extra_link_args=osutil_ldflags,
611 depends=common_depends),
611 depends=common_depends),
612 Extension('hgext.fsmonitor.pywatchman.bser',
612 Extension('hgext.fsmonitor.pywatchman.bser',
613 ['hgext/fsmonitor/pywatchman/bser.c']),
613 ['hgext/fsmonitor/pywatchman/bser.c']),
614 ]
614 ]
615
615
616 sys.path.insert(0, 'contrib/python-zstandard')
616 sys.path.insert(0, 'contrib/python-zstandard')
617 import setup_zstd
617 import setup_zstd
618 extmodules.append(setup_zstd.get_c_extension(name='mercurial.zstd'))
618 extmodules.append(setup_zstd.get_c_extension(name='mercurial.zstd'))
619
619
620 try:
620 try:
621 from distutils import cygwinccompiler
621 from distutils import cygwinccompiler
622
622
623 # the -mno-cygwin option has been deprecated for years
623 # the -mno-cygwin option has been deprecated for years
624 compiler = cygwinccompiler.Mingw32CCompiler
624 compiler = cygwinccompiler.Mingw32CCompiler
625
625
626 class HackedMingw32CCompiler(cygwinccompiler.Mingw32CCompiler):
626 class HackedMingw32CCompiler(cygwinccompiler.Mingw32CCompiler):
627 def __init__(self, *args, **kwargs):
627 def __init__(self, *args, **kwargs):
628 compiler.__init__(self, *args, **kwargs)
628 compiler.__init__(self, *args, **kwargs)
629 for i in 'compiler compiler_so linker_exe linker_so'.split():
629 for i in 'compiler compiler_so linker_exe linker_so'.split():
630 try:
630 try:
631 getattr(self, i).remove('-mno-cygwin')
631 getattr(self, i).remove('-mno-cygwin')
632 except ValueError:
632 except ValueError:
633 pass
633 pass
634
634
635 cygwinccompiler.Mingw32CCompiler = HackedMingw32CCompiler
635 cygwinccompiler.Mingw32CCompiler = HackedMingw32CCompiler
636 except ImportError:
636 except ImportError:
637 # the cygwinccompiler package is not available on some Python
637 # the cygwinccompiler package is not available on some Python
638 # distributions like the ones from the optware project for Synology
638 # distributions like the ones from the optware project for Synology
639 # DiskStation boxes
639 # DiskStation boxes
640 class HackedMingw32CCompiler(object):
640 class HackedMingw32CCompiler(object):
641 pass
641 pass
642
642
643 packagedata = {'mercurial': ['locale/*/LC_MESSAGES/hg.mo',
643 packagedata = {'mercurial': ['locale/*/LC_MESSAGES/hg.mo',
644 'help/*.txt',
644 'help/*.txt',
645 'help/internals/*.txt',
645 'help/internals/*.txt',
646 'default.d/*.rc',
646 'default.d/*.rc',
647 'dummycert.pem']}
647 'dummycert.pem']}
648
648
649 def ordinarypath(p):
649 def ordinarypath(p):
650 return p and p[0] != '.' and p[-1] != '~'
650 return p and p[0] != '.' and p[-1] != '~'
651
651
652 for root in ('templates',):
652 for root in ('templates',):
653 for curdir, dirs, files in os.walk(os.path.join('mercurial', root)):
653 for curdir, dirs, files in os.walk(os.path.join('mercurial', root)):
654 curdir = curdir.split(os.sep, 1)[1]
654 curdir = curdir.split(os.sep, 1)[1]
655 dirs[:] = filter(ordinarypath, dirs)
655 dirs[:] = filter(ordinarypath, dirs)
656 for f in filter(ordinarypath, files):
656 for f in filter(ordinarypath, files):
657 f = os.path.join(curdir, f)
657 f = os.path.join(curdir, f)
658 packagedata['mercurial'].append(f)
658 packagedata['mercurial'].append(f)
659
659
660 datafiles = []
660 datafiles = []
661 setupversion = version
661 setupversion = version
662 extra = {}
662 extra = {}
663
663
664 if py2exeloaded:
664 if py2exeloaded:
665 extra['console'] = [
665 extra['console'] = [
666 {'script':'hg',
666 {'script':'hg',
667 'copyright':'Copyright (C) 2005-2016 Matt Mackall and others',
667 'copyright':'Copyright (C) 2005-2017 Matt Mackall and others',
668 'product_version':version}]
668 'product_version':version}]
669 # sub command of 'build' because 'py2exe' does not handle sub_commands
669 # sub command of 'build' because 'py2exe' does not handle sub_commands
670 build.sub_commands.insert(0, ('build_hgextindex', None))
670 build.sub_commands.insert(0, ('build_hgextindex', None))
671 # put dlls in sub directory so that they won't pollute PATH
671 # put dlls in sub directory so that they won't pollute PATH
672 extra['zipfile'] = 'lib/library.zip'
672 extra['zipfile'] = 'lib/library.zip'
673
673
674 if os.name == 'nt':
674 if os.name == 'nt':
675 # Windows binary file versions for exe/dll files must have the
675 # Windows binary file versions for exe/dll files must have the
676 # form W.X.Y.Z, where W,X,Y,Z are numbers in the range 0..65535
676 # form W.X.Y.Z, where W,X,Y,Z are numbers in the range 0..65535
677 setupversion = version.split('+', 1)[0]
677 setupversion = version.split('+', 1)[0]
678
678
679 if sys.platform == 'darwin' and os.path.exists('/usr/bin/xcodebuild'):
679 if sys.platform == 'darwin' and os.path.exists('/usr/bin/xcodebuild'):
680 version = runcmd(['/usr/bin/xcodebuild', '-version'], {})[0].splitlines()
680 version = runcmd(['/usr/bin/xcodebuild', '-version'], {})[0].splitlines()
681 if version:
681 if version:
682 version = version[0]
682 version = version[0]
683 if sys.version_info[0] == 3:
683 if sys.version_info[0] == 3:
684 version = version.decode('utf-8')
684 version = version.decode('utf-8')
685 xcode4 = (version.startswith('Xcode') and
685 xcode4 = (version.startswith('Xcode') and
686 StrictVersion(version.split()[1]) >= StrictVersion('4.0'))
686 StrictVersion(version.split()[1]) >= StrictVersion('4.0'))
687 xcode51 = re.match(r'^Xcode\s+5\.1', version) is not None
687 xcode51 = re.match(r'^Xcode\s+5\.1', version) is not None
688 else:
688 else:
689 # xcodebuild returns empty on OS X Lion with XCode 4.3 not
689 # xcodebuild returns empty on OS X Lion with XCode 4.3 not
690 # installed, but instead with only command-line tools. Assume
690 # installed, but instead with only command-line tools. Assume
691 # that only happens on >= Lion, thus no PPC support.
691 # that only happens on >= Lion, thus no PPC support.
692 xcode4 = True
692 xcode4 = True
693 xcode51 = False
693 xcode51 = False
694
694
695 # XCode 4.0 dropped support for ppc architecture, which is hardcoded in
695 # XCode 4.0 dropped support for ppc architecture, which is hardcoded in
696 # distutils.sysconfig
696 # distutils.sysconfig
697 if xcode4:
697 if xcode4:
698 os.environ['ARCHFLAGS'] = ''
698 os.environ['ARCHFLAGS'] = ''
699
699
700 # XCode 5.1 changes clang such that it now fails to compile if the
700 # XCode 5.1 changes clang such that it now fails to compile if the
701 # -mno-fused-madd flag is passed, but the version of Python shipped with
701 # -mno-fused-madd flag is passed, but the version of Python shipped with
702 # OS X 10.9 Mavericks includes this flag. This causes problems in all
702 # OS X 10.9 Mavericks includes this flag. This causes problems in all
703 # C extension modules, and a bug has been filed upstream at
703 # C extension modules, and a bug has been filed upstream at
704 # http://bugs.python.org/issue21244. We also need to patch this here
704 # http://bugs.python.org/issue21244. We also need to patch this here
705 # so Mercurial can continue to compile in the meantime.
705 # so Mercurial can continue to compile in the meantime.
706 if xcode51:
706 if xcode51:
707 cflags = get_config_var('CFLAGS')
707 cflags = get_config_var('CFLAGS')
708 if cflags and re.search(r'-mno-fused-madd\b', cflags) is not None:
708 if cflags and re.search(r'-mno-fused-madd\b', cflags) is not None:
709 os.environ['CFLAGS'] = (
709 os.environ['CFLAGS'] = (
710 os.environ.get('CFLAGS', '') + ' -Qunused-arguments')
710 os.environ.get('CFLAGS', '') + ' -Qunused-arguments')
711
711
712 setup(name='mercurial',
712 setup(name='mercurial',
713 version=setupversion,
713 version=setupversion,
714 author='Matt Mackall and many others',
714 author='Matt Mackall and many others',
715 author_email='mercurial@mercurial-scm.org',
715 author_email='mercurial@mercurial-scm.org',
716 url='https://mercurial-scm.org/',
716 url='https://mercurial-scm.org/',
717 download_url='https://mercurial-scm.org/release/',
717 download_url='https://mercurial-scm.org/release/',
718 description=('Fast scalable distributed SCM (revision control, version '
718 description=('Fast scalable distributed SCM (revision control, version '
719 'control) system'),
719 'control) system'),
720 long_description=('Mercurial is a distributed SCM tool written in Python.'
720 long_description=('Mercurial is a distributed SCM tool written in Python.'
721 ' It is used by a number of large projects that require'
721 ' It is used by a number of large projects that require'
722 ' fast, reliable distributed revision control, such as '
722 ' fast, reliable distributed revision control, such as '
723 'Mozilla.'),
723 'Mozilla.'),
724 license='GNU GPLv2 or any later version',
724 license='GNU GPLv2 or any later version',
725 classifiers=[
725 classifiers=[
726 'Development Status :: 6 - Mature',
726 'Development Status :: 6 - Mature',
727 'Environment :: Console',
727 'Environment :: Console',
728 'Intended Audience :: Developers',
728 'Intended Audience :: Developers',
729 'Intended Audience :: System Administrators',
729 'Intended Audience :: System Administrators',
730 'License :: OSI Approved :: GNU General Public License (GPL)',
730 'License :: OSI Approved :: GNU General Public License (GPL)',
731 'Natural Language :: Danish',
731 'Natural Language :: Danish',
732 'Natural Language :: English',
732 'Natural Language :: English',
733 'Natural Language :: German',
733 'Natural Language :: German',
734 'Natural Language :: Italian',
734 'Natural Language :: Italian',
735 'Natural Language :: Japanese',
735 'Natural Language :: Japanese',
736 'Natural Language :: Portuguese (Brazilian)',
736 'Natural Language :: Portuguese (Brazilian)',
737 'Operating System :: Microsoft :: Windows',
737 'Operating System :: Microsoft :: Windows',
738 'Operating System :: OS Independent',
738 'Operating System :: OS Independent',
739 'Operating System :: POSIX',
739 'Operating System :: POSIX',
740 'Programming Language :: C',
740 'Programming Language :: C',
741 'Programming Language :: Python',
741 'Programming Language :: Python',
742 'Topic :: Software Development :: Version Control',
742 'Topic :: Software Development :: Version Control',
743 ],
743 ],
744 scripts=scripts,
744 scripts=scripts,
745 packages=packages,
745 packages=packages,
746 ext_modules=extmodules,
746 ext_modules=extmodules,
747 data_files=datafiles,
747 data_files=datafiles,
748 package_data=packagedata,
748 package_data=packagedata,
749 cmdclass=cmdclass,
749 cmdclass=cmdclass,
750 distclass=hgdist,
750 distclass=hgdist,
751 options={'py2exe': {'packages': ['hgext', 'email']},
751 options={'py2exe': {'packages': ['hgext', 'email']},
752 'bdist_mpkg': {'zipdist': False,
752 'bdist_mpkg': {'zipdist': False,
753 'license': 'COPYING',
753 'license': 'COPYING',
754 'readme': 'contrib/macosx/Readme.html',
754 'readme': 'contrib/macosx/Readme.html',
755 'welcome': 'contrib/macosx/Welcome.html',
755 'welcome': 'contrib/macosx/Welcome.html',
756 },
756 },
757 },
757 },
758 **extra)
758 **extra)
@@ -1,3174 +1,3174 b''
1 Short help:
1 Short help:
2
2
3 $ hg
3 $ hg
4 Mercurial Distributed SCM
4 Mercurial Distributed SCM
5
5
6 basic commands:
6 basic commands:
7
7
8 add add the specified files on the next commit
8 add add the specified files on the next commit
9 annotate show changeset information by line for each file
9 annotate show changeset information by line for each file
10 clone make a copy of an existing repository
10 clone make a copy of an existing repository
11 commit commit the specified files or all outstanding changes
11 commit commit the specified files or all outstanding changes
12 diff diff repository (or selected files)
12 diff diff repository (or selected files)
13 export dump the header and diffs for one or more changesets
13 export dump the header and diffs for one or more changesets
14 forget forget the specified files on the next commit
14 forget forget the specified files on the next commit
15 init create a new repository in the given directory
15 init create a new repository in the given directory
16 log show revision history of entire repository or files
16 log show revision history of entire repository or files
17 merge merge another revision into working directory
17 merge merge another revision into working directory
18 pull pull changes from the specified source
18 pull pull changes from the specified source
19 push push changes to the specified destination
19 push push changes to the specified destination
20 remove remove the specified files on the next commit
20 remove remove the specified files on the next commit
21 serve start stand-alone webserver
21 serve start stand-alone webserver
22 status show changed files in the working directory
22 status show changed files in the working directory
23 summary summarize working directory state
23 summary summarize working directory state
24 update update working directory (or switch revisions)
24 update update working directory (or switch revisions)
25
25
26 (use 'hg help' for the full list of commands or 'hg -v' for details)
26 (use 'hg help' for the full list of commands or 'hg -v' for details)
27
27
28 $ hg -q
28 $ hg -q
29 add add the specified files on the next commit
29 add add the specified files on the next commit
30 annotate show changeset information by line for each file
30 annotate show changeset information by line for each file
31 clone make a copy of an existing repository
31 clone make a copy of an existing repository
32 commit commit the specified files or all outstanding changes
32 commit commit the specified files or all outstanding changes
33 diff diff repository (or selected files)
33 diff diff repository (or selected files)
34 export dump the header and diffs for one or more changesets
34 export dump the header and diffs for one or more changesets
35 forget forget the specified files on the next commit
35 forget forget the specified files on the next commit
36 init create a new repository in the given directory
36 init create a new repository in the given directory
37 log show revision history of entire repository or files
37 log show revision history of entire repository or files
38 merge merge another revision into working directory
38 merge merge another revision into working directory
39 pull pull changes from the specified source
39 pull pull changes from the specified source
40 push push changes to the specified destination
40 push push changes to the specified destination
41 remove remove the specified files on the next commit
41 remove remove the specified files on the next commit
42 serve start stand-alone webserver
42 serve start stand-alone webserver
43 status show changed files in the working directory
43 status show changed files in the working directory
44 summary summarize working directory state
44 summary summarize working directory state
45 update update working directory (or switch revisions)
45 update update working directory (or switch revisions)
46
46
47 $ hg help
47 $ hg help
48 Mercurial Distributed SCM
48 Mercurial Distributed SCM
49
49
50 list of commands:
50 list of commands:
51
51
52 add add the specified files on the next commit
52 add add the specified files on the next commit
53 addremove add all new files, delete all missing files
53 addremove add all new files, delete all missing files
54 annotate show changeset information by line for each file
54 annotate show changeset information by line for each file
55 archive create an unversioned archive of a repository revision
55 archive create an unversioned archive of a repository revision
56 backout reverse effect of earlier changeset
56 backout reverse effect of earlier changeset
57 bisect subdivision search of changesets
57 bisect subdivision search of changesets
58 bookmarks create a new bookmark or list existing bookmarks
58 bookmarks create a new bookmark or list existing bookmarks
59 branch set or show the current branch name
59 branch set or show the current branch name
60 branches list repository named branches
60 branches list repository named branches
61 bundle create a changegroup file
61 bundle create a changegroup file
62 cat output the current or given revision of files
62 cat output the current or given revision of files
63 clone make a copy of an existing repository
63 clone make a copy of an existing repository
64 commit commit the specified files or all outstanding changes
64 commit commit the specified files or all outstanding changes
65 config show combined config settings from all hgrc files
65 config show combined config settings from all hgrc files
66 copy mark files as copied for the next commit
66 copy mark files as copied for the next commit
67 diff diff repository (or selected files)
67 diff diff repository (or selected files)
68 export dump the header and diffs for one or more changesets
68 export dump the header and diffs for one or more changesets
69 files list tracked files
69 files list tracked files
70 forget forget the specified files on the next commit
70 forget forget the specified files on the next commit
71 graft copy changes from other branches onto the current branch
71 graft copy changes from other branches onto the current branch
72 grep search revision history for a pattern in specified files
72 grep search revision history for a pattern in specified files
73 heads show branch heads
73 heads show branch heads
74 help show help for a given topic or a help overview
74 help show help for a given topic or a help overview
75 identify identify the working directory or specified revision
75 identify identify the working directory or specified revision
76 import import an ordered set of patches
76 import import an ordered set of patches
77 incoming show new changesets found in source
77 incoming show new changesets found in source
78 init create a new repository in the given directory
78 init create a new repository in the given directory
79 log show revision history of entire repository or files
79 log show revision history of entire repository or files
80 manifest output the current or given revision of the project manifest
80 manifest output the current or given revision of the project manifest
81 merge merge another revision into working directory
81 merge merge another revision into working directory
82 outgoing show changesets not found in the destination
82 outgoing show changesets not found in the destination
83 paths show aliases for remote repositories
83 paths show aliases for remote repositories
84 phase set or show the current phase name
84 phase set or show the current phase name
85 pull pull changes from the specified source
85 pull pull changes from the specified source
86 push push changes to the specified destination
86 push push changes to the specified destination
87 recover roll back an interrupted transaction
87 recover roll back an interrupted transaction
88 remove remove the specified files on the next commit
88 remove remove the specified files on the next commit
89 rename rename files; equivalent of copy + remove
89 rename rename files; equivalent of copy + remove
90 resolve redo merges or set/view the merge status of files
90 resolve redo merges or set/view the merge status of files
91 revert restore files to their checkout state
91 revert restore files to their checkout state
92 root print the root (top) of the current working directory
92 root print the root (top) of the current working directory
93 serve start stand-alone webserver
93 serve start stand-alone webserver
94 status show changed files in the working directory
94 status show changed files in the working directory
95 summary summarize working directory state
95 summary summarize working directory state
96 tag add one or more tags for the current or given revision
96 tag add one or more tags for the current or given revision
97 tags list repository tags
97 tags list repository tags
98 unbundle apply one or more changegroup files
98 unbundle apply one or more changegroup files
99 update update working directory (or switch revisions)
99 update update working directory (or switch revisions)
100 verify verify the integrity of the repository
100 verify verify the integrity of the repository
101 version output version and copyright information
101 version output version and copyright information
102
102
103 additional help topics:
103 additional help topics:
104
104
105 config Configuration Files
105 config Configuration Files
106 dates Date Formats
106 dates Date Formats
107 diffs Diff Formats
107 diffs Diff Formats
108 environment Environment Variables
108 environment Environment Variables
109 extensions Using Additional Features
109 extensions Using Additional Features
110 filesets Specifying File Sets
110 filesets Specifying File Sets
111 glossary Glossary
111 glossary Glossary
112 hgignore Syntax for Mercurial Ignore Files
112 hgignore Syntax for Mercurial Ignore Files
113 hgweb Configuring hgweb
113 hgweb Configuring hgweb
114 internals Technical implementation topics
114 internals Technical implementation topics
115 merge-tools Merge Tools
115 merge-tools Merge Tools
116 patterns File Name Patterns
116 patterns File Name Patterns
117 phases Working with Phases
117 phases Working with Phases
118 revisions Specifying Revisions
118 revisions Specifying Revisions
119 scripting Using Mercurial from scripts and automation
119 scripting Using Mercurial from scripts and automation
120 subrepos Subrepositories
120 subrepos Subrepositories
121 templating Template Usage
121 templating Template Usage
122 urls URL Paths
122 urls URL Paths
123
123
124 (use 'hg help -v' to show built-in aliases and global options)
124 (use 'hg help -v' to show built-in aliases and global options)
125
125
126 $ hg -q help
126 $ hg -q help
127 add add the specified files on the next commit
127 add add the specified files on the next commit
128 addremove add all new files, delete all missing files
128 addremove add all new files, delete all missing files
129 annotate show changeset information by line for each file
129 annotate show changeset information by line for each file
130 archive create an unversioned archive of a repository revision
130 archive create an unversioned archive of a repository revision
131 backout reverse effect of earlier changeset
131 backout reverse effect of earlier changeset
132 bisect subdivision search of changesets
132 bisect subdivision search of changesets
133 bookmarks create a new bookmark or list existing bookmarks
133 bookmarks create a new bookmark or list existing bookmarks
134 branch set or show the current branch name
134 branch set or show the current branch name
135 branches list repository named branches
135 branches list repository named branches
136 bundle create a changegroup file
136 bundle create a changegroup file
137 cat output the current or given revision of files
137 cat output the current or given revision of files
138 clone make a copy of an existing repository
138 clone make a copy of an existing repository
139 commit commit the specified files or all outstanding changes
139 commit commit the specified files or all outstanding changes
140 config show combined config settings from all hgrc files
140 config show combined config settings from all hgrc files
141 copy mark files as copied for the next commit
141 copy mark files as copied for the next commit
142 diff diff repository (or selected files)
142 diff diff repository (or selected files)
143 export dump the header and diffs for one or more changesets
143 export dump the header and diffs for one or more changesets
144 files list tracked files
144 files list tracked files
145 forget forget the specified files on the next commit
145 forget forget the specified files on the next commit
146 graft copy changes from other branches onto the current branch
146 graft copy changes from other branches onto the current branch
147 grep search revision history for a pattern in specified files
147 grep search revision history for a pattern in specified files
148 heads show branch heads
148 heads show branch heads
149 help show help for a given topic or a help overview
149 help show help for a given topic or a help overview
150 identify identify the working directory or specified revision
150 identify identify the working directory or specified revision
151 import import an ordered set of patches
151 import import an ordered set of patches
152 incoming show new changesets found in source
152 incoming show new changesets found in source
153 init create a new repository in the given directory
153 init create a new repository in the given directory
154 log show revision history of entire repository or files
154 log show revision history of entire repository or files
155 manifest output the current or given revision of the project manifest
155 manifest output the current or given revision of the project manifest
156 merge merge another revision into working directory
156 merge merge another revision into working directory
157 outgoing show changesets not found in the destination
157 outgoing show changesets not found in the destination
158 paths show aliases for remote repositories
158 paths show aliases for remote repositories
159 phase set or show the current phase name
159 phase set or show the current phase name
160 pull pull changes from the specified source
160 pull pull changes from the specified source
161 push push changes to the specified destination
161 push push changes to the specified destination
162 recover roll back an interrupted transaction
162 recover roll back an interrupted transaction
163 remove remove the specified files on the next commit
163 remove remove the specified files on the next commit
164 rename rename files; equivalent of copy + remove
164 rename rename files; equivalent of copy + remove
165 resolve redo merges or set/view the merge status of files
165 resolve redo merges or set/view the merge status of files
166 revert restore files to their checkout state
166 revert restore files to their checkout state
167 root print the root (top) of the current working directory
167 root print the root (top) of the current working directory
168 serve start stand-alone webserver
168 serve start stand-alone webserver
169 status show changed files in the working directory
169 status show changed files in the working directory
170 summary summarize working directory state
170 summary summarize working directory state
171 tag add one or more tags for the current or given revision
171 tag add one or more tags for the current or given revision
172 tags list repository tags
172 tags list repository tags
173 unbundle apply one or more changegroup files
173 unbundle apply one or more changegroup files
174 update update working directory (or switch revisions)
174 update update working directory (or switch revisions)
175 verify verify the integrity of the repository
175 verify verify the integrity of the repository
176 version output version and copyright information
176 version output version and copyright information
177
177
178 additional help topics:
178 additional help topics:
179
179
180 config Configuration Files
180 config Configuration Files
181 dates Date Formats
181 dates Date Formats
182 diffs Diff Formats
182 diffs Diff Formats
183 environment Environment Variables
183 environment Environment Variables
184 extensions Using Additional Features
184 extensions Using Additional Features
185 filesets Specifying File Sets
185 filesets Specifying File Sets
186 glossary Glossary
186 glossary Glossary
187 hgignore Syntax for Mercurial Ignore Files
187 hgignore Syntax for Mercurial Ignore Files
188 hgweb Configuring hgweb
188 hgweb Configuring hgweb
189 internals Technical implementation topics
189 internals Technical implementation topics
190 merge-tools Merge Tools
190 merge-tools Merge Tools
191 patterns File Name Patterns
191 patterns File Name Patterns
192 phases Working with Phases
192 phases Working with Phases
193 revisions Specifying Revisions
193 revisions Specifying Revisions
194 scripting Using Mercurial from scripts and automation
194 scripting Using Mercurial from scripts and automation
195 subrepos Subrepositories
195 subrepos Subrepositories
196 templating Template Usage
196 templating Template Usage
197 urls URL Paths
197 urls URL Paths
198
198
199 Test extension help:
199 Test extension help:
200 $ hg help extensions --config extensions.rebase= --config extensions.children=
200 $ hg help extensions --config extensions.rebase= --config extensions.children=
201 Using Additional Features
201 Using Additional Features
202 """""""""""""""""""""""""
202 """""""""""""""""""""""""
203
203
204 Mercurial has the ability to add new features through the use of
204 Mercurial has the ability to add new features through the use of
205 extensions. Extensions may add new commands, add options to existing
205 extensions. Extensions may add new commands, add options to existing
206 commands, change the default behavior of commands, or implement hooks.
206 commands, change the default behavior of commands, or implement hooks.
207
207
208 To enable the "foo" extension, either shipped with Mercurial or in the
208 To enable the "foo" extension, either shipped with Mercurial or in the
209 Python search path, create an entry for it in your configuration file,
209 Python search path, create an entry for it in your configuration file,
210 like this:
210 like this:
211
211
212 [extensions]
212 [extensions]
213 foo =
213 foo =
214
214
215 You may also specify the full path to an extension:
215 You may also specify the full path to an extension:
216
216
217 [extensions]
217 [extensions]
218 myfeature = ~/.hgext/myfeature.py
218 myfeature = ~/.hgext/myfeature.py
219
219
220 See 'hg help config' for more information on configuration files.
220 See 'hg help config' for more information on configuration files.
221
221
222 Extensions are not loaded by default for a variety of reasons: they can
222 Extensions are not loaded by default for a variety of reasons: they can
223 increase startup overhead; they may be meant for advanced usage only; they
223 increase startup overhead; they may be meant for advanced usage only; they
224 may provide potentially dangerous abilities (such as letting you destroy
224 may provide potentially dangerous abilities (such as letting you destroy
225 or modify history); they might not be ready for prime time; or they may
225 or modify history); they might not be ready for prime time; or they may
226 alter some usual behaviors of stock Mercurial. It is thus up to the user
226 alter some usual behaviors of stock Mercurial. It is thus up to the user
227 to activate extensions as needed.
227 to activate extensions as needed.
228
228
229 To explicitly disable an extension enabled in a configuration file of
229 To explicitly disable an extension enabled in a configuration file of
230 broader scope, prepend its path with !:
230 broader scope, prepend its path with !:
231
231
232 [extensions]
232 [extensions]
233 # disabling extension bar residing in /path/to/extension/bar.py
233 # disabling extension bar residing in /path/to/extension/bar.py
234 bar = !/path/to/extension/bar.py
234 bar = !/path/to/extension/bar.py
235 # ditto, but no path was supplied for extension baz
235 # ditto, but no path was supplied for extension baz
236 baz = !
236 baz = !
237
237
238 enabled extensions:
238 enabled extensions:
239
239
240 children command to display child changesets (DEPRECATED)
240 children command to display child changesets (DEPRECATED)
241 rebase command to move sets of revisions to a different ancestor
241 rebase command to move sets of revisions to a different ancestor
242
242
243 disabled extensions:
243 disabled extensions:
244
244
245 acl hooks for controlling repository access
245 acl hooks for controlling repository access
246 blackbox log repository events to a blackbox for debugging
246 blackbox log repository events to a blackbox for debugging
247 bugzilla hooks for integrating with the Bugzilla bug tracker
247 bugzilla hooks for integrating with the Bugzilla bug tracker
248 censor erase file content at a given revision
248 censor erase file content at a given revision
249 churn command to display statistics about repository history
249 churn command to display statistics about repository history
250 clonebundles advertise pre-generated bundles to seed clones
250 clonebundles advertise pre-generated bundles to seed clones
251 color colorize output from some commands
251 color colorize output from some commands
252 convert import revisions from foreign VCS repositories into
252 convert import revisions from foreign VCS repositories into
253 Mercurial
253 Mercurial
254 eol automatically manage newlines in repository files
254 eol automatically manage newlines in repository files
255 extdiff command to allow external programs to compare revisions
255 extdiff command to allow external programs to compare revisions
256 factotum http authentication with factotum
256 factotum http authentication with factotum
257 gpg commands to sign and verify changesets
257 gpg commands to sign and verify changesets
258 hgk browse the repository in a graphical way
258 hgk browse the repository in a graphical way
259 highlight syntax highlighting for hgweb (requires Pygments)
259 highlight syntax highlighting for hgweb (requires Pygments)
260 histedit interactive history editing
260 histedit interactive history editing
261 keyword expand keywords in tracked files
261 keyword expand keywords in tracked files
262 largefiles track large binary files
262 largefiles track large binary files
263 mq manage a stack of patches
263 mq manage a stack of patches
264 notify hooks for sending email push notifications
264 notify hooks for sending email push notifications
265 pager browse command output with an external pager
265 pager browse command output with an external pager
266 patchbomb command to send changesets as (a series of) patch emails
266 patchbomb command to send changesets as (a series of) patch emails
267 purge command to delete untracked files from the working
267 purge command to delete untracked files from the working
268 directory
268 directory
269 relink recreates hardlinks between repository clones
269 relink recreates hardlinks between repository clones
270 schemes extend schemes with shortcuts to repository swarms
270 schemes extend schemes with shortcuts to repository swarms
271 share share a common history between several working directories
271 share share a common history between several working directories
272 shelve save and restore changes to the working directory
272 shelve save and restore changes to the working directory
273 strip strip changesets and their descendants from history
273 strip strip changesets and their descendants from history
274 transplant command to transplant changesets from another branch
274 transplant command to transplant changesets from another branch
275 win32mbcs allow the use of MBCS paths with problematic encodings
275 win32mbcs allow the use of MBCS paths with problematic encodings
276 zeroconf discover and advertise repositories on the local network
276 zeroconf discover and advertise repositories on the local network
277
277
278 Verify that extension keywords appear in help templates
278 Verify that extension keywords appear in help templates
279
279
280 $ hg help --config extensions.transplant= templating|grep transplant > /dev/null
280 $ hg help --config extensions.transplant= templating|grep transplant > /dev/null
281
281
282 Test short command list with verbose option
282 Test short command list with verbose option
283
283
284 $ hg -v help shortlist
284 $ hg -v help shortlist
285 Mercurial Distributed SCM
285 Mercurial Distributed SCM
286
286
287 basic commands:
287 basic commands:
288
288
289 add add the specified files on the next commit
289 add add the specified files on the next commit
290 annotate, blame
290 annotate, blame
291 show changeset information by line for each file
291 show changeset information by line for each file
292 clone make a copy of an existing repository
292 clone make a copy of an existing repository
293 commit, ci commit the specified files or all outstanding changes
293 commit, ci commit the specified files or all outstanding changes
294 diff diff repository (or selected files)
294 diff diff repository (or selected files)
295 export dump the header and diffs for one or more changesets
295 export dump the header and diffs for one or more changesets
296 forget forget the specified files on the next commit
296 forget forget the specified files on the next commit
297 init create a new repository in the given directory
297 init create a new repository in the given directory
298 log, history show revision history of entire repository or files
298 log, history show revision history of entire repository or files
299 merge merge another revision into working directory
299 merge merge another revision into working directory
300 pull pull changes from the specified source
300 pull pull changes from the specified source
301 push push changes to the specified destination
301 push push changes to the specified destination
302 remove, rm remove the specified files on the next commit
302 remove, rm remove the specified files on the next commit
303 serve start stand-alone webserver
303 serve start stand-alone webserver
304 status, st show changed files in the working directory
304 status, st show changed files in the working directory
305 summary, sum summarize working directory state
305 summary, sum summarize working directory state
306 update, up, checkout, co
306 update, up, checkout, co
307 update working directory (or switch revisions)
307 update working directory (or switch revisions)
308
308
309 global options ([+] can be repeated):
309 global options ([+] can be repeated):
310
310
311 -R --repository REPO repository root directory or name of overlay bundle
311 -R --repository REPO repository root directory or name of overlay bundle
312 file
312 file
313 --cwd DIR change working directory
313 --cwd DIR change working directory
314 -y --noninteractive do not prompt, automatically pick the first choice for
314 -y --noninteractive do not prompt, automatically pick the first choice for
315 all prompts
315 all prompts
316 -q --quiet suppress output
316 -q --quiet suppress output
317 -v --verbose enable additional output
317 -v --verbose enable additional output
318 --config CONFIG [+] set/override config option (use 'section.name=value')
318 --config CONFIG [+] set/override config option (use 'section.name=value')
319 --debug enable debugging output
319 --debug enable debugging output
320 --debugger start debugger
320 --debugger start debugger
321 --encoding ENCODE set the charset encoding (default: ascii)
321 --encoding ENCODE set the charset encoding (default: ascii)
322 --encodingmode MODE set the charset encoding mode (default: strict)
322 --encodingmode MODE set the charset encoding mode (default: strict)
323 --traceback always print a traceback on exception
323 --traceback always print a traceback on exception
324 --time time how long the command takes
324 --time time how long the command takes
325 --profile print command execution profile
325 --profile print command execution profile
326 --version output version information and exit
326 --version output version information and exit
327 -h --help display help and exit
327 -h --help display help and exit
328 --hidden consider hidden changesets
328 --hidden consider hidden changesets
329
329
330 (use 'hg help' for the full list of commands)
330 (use 'hg help' for the full list of commands)
331
331
332 $ hg add -h
332 $ hg add -h
333 hg add [OPTION]... [FILE]...
333 hg add [OPTION]... [FILE]...
334
334
335 add the specified files on the next commit
335 add the specified files on the next commit
336
336
337 Schedule files to be version controlled and added to the repository.
337 Schedule files to be version controlled and added to the repository.
338
338
339 The files will be added to the repository at the next commit. To undo an
339 The files will be added to the repository at the next commit. To undo an
340 add before that, see 'hg forget'.
340 add before that, see 'hg forget'.
341
341
342 If no names are given, add all files to the repository (except files
342 If no names are given, add all files to the repository (except files
343 matching ".hgignore").
343 matching ".hgignore").
344
344
345 Returns 0 if all files are successfully added.
345 Returns 0 if all files are successfully added.
346
346
347 options ([+] can be repeated):
347 options ([+] can be repeated):
348
348
349 -I --include PATTERN [+] include names matching the given patterns
349 -I --include PATTERN [+] include names matching the given patterns
350 -X --exclude PATTERN [+] exclude names matching the given patterns
350 -X --exclude PATTERN [+] exclude names matching the given patterns
351 -S --subrepos recurse into subrepositories
351 -S --subrepos recurse into subrepositories
352 -n --dry-run do not perform actions, just print output
352 -n --dry-run do not perform actions, just print output
353
353
354 (some details hidden, use --verbose to show complete help)
354 (some details hidden, use --verbose to show complete help)
355
355
356 Verbose help for add
356 Verbose help for add
357
357
358 $ hg add -hv
358 $ hg add -hv
359 hg add [OPTION]... [FILE]...
359 hg add [OPTION]... [FILE]...
360
360
361 add the specified files on the next commit
361 add the specified files on the next commit
362
362
363 Schedule files to be version controlled and added to the repository.
363 Schedule files to be version controlled and added to the repository.
364
364
365 The files will be added to the repository at the next commit. To undo an
365 The files will be added to the repository at the next commit. To undo an
366 add before that, see 'hg forget'.
366 add before that, see 'hg forget'.
367
367
368 If no names are given, add all files to the repository (except files
368 If no names are given, add all files to the repository (except files
369 matching ".hgignore").
369 matching ".hgignore").
370
370
371 Examples:
371 Examples:
372
372
373 - New (unknown) files are added automatically by 'hg add':
373 - New (unknown) files are added automatically by 'hg add':
374
374
375 $ ls
375 $ ls
376 foo.c
376 foo.c
377 $ hg status
377 $ hg status
378 ? foo.c
378 ? foo.c
379 $ hg add
379 $ hg add
380 adding foo.c
380 adding foo.c
381 $ hg status
381 $ hg status
382 A foo.c
382 A foo.c
383
383
384 - Specific files to be added can be specified:
384 - Specific files to be added can be specified:
385
385
386 $ ls
386 $ ls
387 bar.c foo.c
387 bar.c foo.c
388 $ hg status
388 $ hg status
389 ? bar.c
389 ? bar.c
390 ? foo.c
390 ? foo.c
391 $ hg add bar.c
391 $ hg add bar.c
392 $ hg status
392 $ hg status
393 A bar.c
393 A bar.c
394 ? foo.c
394 ? foo.c
395
395
396 Returns 0 if all files are successfully added.
396 Returns 0 if all files are successfully added.
397
397
398 options ([+] can be repeated):
398 options ([+] can be repeated):
399
399
400 -I --include PATTERN [+] include names matching the given patterns
400 -I --include PATTERN [+] include names matching the given patterns
401 -X --exclude PATTERN [+] exclude names matching the given patterns
401 -X --exclude PATTERN [+] exclude names matching the given patterns
402 -S --subrepos recurse into subrepositories
402 -S --subrepos recurse into subrepositories
403 -n --dry-run do not perform actions, just print output
403 -n --dry-run do not perform actions, just print output
404
404
405 global options ([+] can be repeated):
405 global options ([+] can be repeated):
406
406
407 -R --repository REPO repository root directory or name of overlay bundle
407 -R --repository REPO repository root directory or name of overlay bundle
408 file
408 file
409 --cwd DIR change working directory
409 --cwd DIR change working directory
410 -y --noninteractive do not prompt, automatically pick the first choice for
410 -y --noninteractive do not prompt, automatically pick the first choice for
411 all prompts
411 all prompts
412 -q --quiet suppress output
412 -q --quiet suppress output
413 -v --verbose enable additional output
413 -v --verbose enable additional output
414 --config CONFIG [+] set/override config option (use 'section.name=value')
414 --config CONFIG [+] set/override config option (use 'section.name=value')
415 --debug enable debugging output
415 --debug enable debugging output
416 --debugger start debugger
416 --debugger start debugger
417 --encoding ENCODE set the charset encoding (default: ascii)
417 --encoding ENCODE set the charset encoding (default: ascii)
418 --encodingmode MODE set the charset encoding mode (default: strict)
418 --encodingmode MODE set the charset encoding mode (default: strict)
419 --traceback always print a traceback on exception
419 --traceback always print a traceback on exception
420 --time time how long the command takes
420 --time time how long the command takes
421 --profile print command execution profile
421 --profile print command execution profile
422 --version output version information and exit
422 --version output version information and exit
423 -h --help display help and exit
423 -h --help display help and exit
424 --hidden consider hidden changesets
424 --hidden consider hidden changesets
425
425
426 Test the textwidth config option
426 Test the textwidth config option
427
427
428 $ hg root -h --config ui.textwidth=50
428 $ hg root -h --config ui.textwidth=50
429 hg root
429 hg root
430
430
431 print the root (top) of the current working
431 print the root (top) of the current working
432 directory
432 directory
433
433
434 Print the root directory of the current
434 Print the root directory of the current
435 repository.
435 repository.
436
436
437 Returns 0 on success.
437 Returns 0 on success.
438
438
439 (some details hidden, use --verbose to show
439 (some details hidden, use --verbose to show
440 complete help)
440 complete help)
441
441
442 Test help option with version option
442 Test help option with version option
443
443
444 $ hg add -h --version
444 $ hg add -h --version
445 Mercurial Distributed SCM (version *) (glob)
445 Mercurial Distributed SCM (version *) (glob)
446 (see https://mercurial-scm.org for more information)
446 (see https://mercurial-scm.org for more information)
447
447
448 Copyright (C) 2005-2016 Matt Mackall and others
448 Copyright (C) 2005-* Matt Mackall and others (glob)
449 This is free software; see the source for copying conditions. There is NO
449 This is free software; see the source for copying conditions. There is NO
450 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
450 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
451
451
452 $ hg add --skjdfks
452 $ hg add --skjdfks
453 hg add: option --skjdfks not recognized
453 hg add: option --skjdfks not recognized
454 hg add [OPTION]... [FILE]...
454 hg add [OPTION]... [FILE]...
455
455
456 add the specified files on the next commit
456 add the specified files on the next commit
457
457
458 options ([+] can be repeated):
458 options ([+] can be repeated):
459
459
460 -I --include PATTERN [+] include names matching the given patterns
460 -I --include PATTERN [+] include names matching the given patterns
461 -X --exclude PATTERN [+] exclude names matching the given patterns
461 -X --exclude PATTERN [+] exclude names matching the given patterns
462 -S --subrepos recurse into subrepositories
462 -S --subrepos recurse into subrepositories
463 -n --dry-run do not perform actions, just print output
463 -n --dry-run do not perform actions, just print output
464
464
465 (use 'hg add -h' to show more help)
465 (use 'hg add -h' to show more help)
466 [255]
466 [255]
467
467
468 Test ambiguous command help
468 Test ambiguous command help
469
469
470 $ hg help ad
470 $ hg help ad
471 list of commands:
471 list of commands:
472
472
473 add add the specified files on the next commit
473 add add the specified files on the next commit
474 addremove add all new files, delete all missing files
474 addremove add all new files, delete all missing files
475
475
476 (use 'hg help -v ad' to show built-in aliases and global options)
476 (use 'hg help -v ad' to show built-in aliases and global options)
477
477
478 Test command without options
478 Test command without options
479
479
480 $ hg help verify
480 $ hg help verify
481 hg verify
481 hg verify
482
482
483 verify the integrity of the repository
483 verify the integrity of the repository
484
484
485 Verify the integrity of the current repository.
485 Verify the integrity of the current repository.
486
486
487 This will perform an extensive check of the repository's integrity,
487 This will perform an extensive check of the repository's integrity,
488 validating the hashes and checksums of each entry in the changelog,
488 validating the hashes and checksums of each entry in the changelog,
489 manifest, and tracked files, as well as the integrity of their crosslinks
489 manifest, and tracked files, as well as the integrity of their crosslinks
490 and indices.
490 and indices.
491
491
492 Please see https://mercurial-scm.org/wiki/RepositoryCorruption for more
492 Please see https://mercurial-scm.org/wiki/RepositoryCorruption for more
493 information about recovery from corruption of the repository.
493 information about recovery from corruption of the repository.
494
494
495 Returns 0 on success, 1 if errors are encountered.
495 Returns 0 on success, 1 if errors are encountered.
496
496
497 (some details hidden, use --verbose to show complete help)
497 (some details hidden, use --verbose to show complete help)
498
498
499 $ hg help diff
499 $ hg help diff
500 hg diff [OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...
500 hg diff [OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...
501
501
502 diff repository (or selected files)
502 diff repository (or selected files)
503
503
504 Show differences between revisions for the specified files.
504 Show differences between revisions for the specified files.
505
505
506 Differences between files are shown using the unified diff format.
506 Differences between files are shown using the unified diff format.
507
507
508 Note:
508 Note:
509 'hg diff' may generate unexpected results for merges, as it will
509 'hg diff' may generate unexpected results for merges, as it will
510 default to comparing against the working directory's first parent
510 default to comparing against the working directory's first parent
511 changeset if no revisions are specified.
511 changeset if no revisions are specified.
512
512
513 When two revision arguments are given, then changes are shown between
513 When two revision arguments are given, then changes are shown between
514 those revisions. If only one revision is specified then that revision is
514 those revisions. If only one revision is specified then that revision is
515 compared to the working directory, and, when no revisions are specified,
515 compared to the working directory, and, when no revisions are specified,
516 the working directory files are compared to its first parent.
516 the working directory files are compared to its first parent.
517
517
518 Alternatively you can specify -c/--change with a revision to see the
518 Alternatively you can specify -c/--change with a revision to see the
519 changes in that changeset relative to its first parent.
519 changes in that changeset relative to its first parent.
520
520
521 Without the -a/--text option, diff will avoid generating diffs of files it
521 Without the -a/--text option, diff will avoid generating diffs of files it
522 detects as binary. With -a, diff will generate a diff anyway, probably
522 detects as binary. With -a, diff will generate a diff anyway, probably
523 with undesirable results.
523 with undesirable results.
524
524
525 Use the -g/--git option to generate diffs in the git extended diff format.
525 Use the -g/--git option to generate diffs in the git extended diff format.
526 For more information, read 'hg help diffs'.
526 For more information, read 'hg help diffs'.
527
527
528 Returns 0 on success.
528 Returns 0 on success.
529
529
530 options ([+] can be repeated):
530 options ([+] can be repeated):
531
531
532 -r --rev REV [+] revision
532 -r --rev REV [+] revision
533 -c --change REV change made by revision
533 -c --change REV change made by revision
534 -a --text treat all files as text
534 -a --text treat all files as text
535 -g --git use git extended diff format
535 -g --git use git extended diff format
536 --nodates omit dates from diff headers
536 --nodates omit dates from diff headers
537 --noprefix omit a/ and b/ prefixes from filenames
537 --noprefix omit a/ and b/ prefixes from filenames
538 -p --show-function show which function each change is in
538 -p --show-function show which function each change is in
539 --reverse produce a diff that undoes the changes
539 --reverse produce a diff that undoes the changes
540 -w --ignore-all-space ignore white space when comparing lines
540 -w --ignore-all-space ignore white space when comparing lines
541 -b --ignore-space-change ignore changes in the amount of white space
541 -b --ignore-space-change ignore changes in the amount of white space
542 -B --ignore-blank-lines ignore changes whose lines are all blank
542 -B --ignore-blank-lines ignore changes whose lines are all blank
543 -U --unified NUM number of lines of context to show
543 -U --unified NUM number of lines of context to show
544 --stat output diffstat-style summary of changes
544 --stat output diffstat-style summary of changes
545 --root DIR produce diffs relative to subdirectory
545 --root DIR produce diffs relative to subdirectory
546 -I --include PATTERN [+] include names matching the given patterns
546 -I --include PATTERN [+] include names matching the given patterns
547 -X --exclude PATTERN [+] exclude names matching the given patterns
547 -X --exclude PATTERN [+] exclude names matching the given patterns
548 -S --subrepos recurse into subrepositories
548 -S --subrepos recurse into subrepositories
549
549
550 (some details hidden, use --verbose to show complete help)
550 (some details hidden, use --verbose to show complete help)
551
551
552 $ hg help status
552 $ hg help status
553 hg status [OPTION]... [FILE]...
553 hg status [OPTION]... [FILE]...
554
554
555 aliases: st
555 aliases: st
556
556
557 show changed files in the working directory
557 show changed files in the working directory
558
558
559 Show status of files in the repository. If names are given, only files
559 Show status of files in the repository. If names are given, only files
560 that match are shown. Files that are clean or ignored or the source of a
560 that match are shown. Files that are clean or ignored or the source of a
561 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
561 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
562 -C/--copies or -A/--all are given. Unless options described with "show
562 -C/--copies or -A/--all are given. Unless options described with "show
563 only ..." are given, the options -mardu are used.
563 only ..." are given, the options -mardu are used.
564
564
565 Option -q/--quiet hides untracked (unknown and ignored) files unless
565 Option -q/--quiet hides untracked (unknown and ignored) files unless
566 explicitly requested with -u/--unknown or -i/--ignored.
566 explicitly requested with -u/--unknown or -i/--ignored.
567
567
568 Note:
568 Note:
569 'hg status' may appear to disagree with diff if permissions have
569 'hg status' may appear to disagree with diff if permissions have
570 changed or a merge has occurred. The standard diff format does not
570 changed or a merge has occurred. The standard diff format does not
571 report permission changes and diff only reports changes relative to one
571 report permission changes and diff only reports changes relative to one
572 merge parent.
572 merge parent.
573
573
574 If one revision is given, it is used as the base revision. If two
574 If one revision is given, it is used as the base revision. If two
575 revisions are given, the differences between them are shown. The --change
575 revisions are given, the differences between them are shown. The --change
576 option can also be used as a shortcut to list the changed files of a
576 option can also be used as a shortcut to list the changed files of a
577 revision from its first parent.
577 revision from its first parent.
578
578
579 The codes used to show the status of files are:
579 The codes used to show the status of files are:
580
580
581 M = modified
581 M = modified
582 A = added
582 A = added
583 R = removed
583 R = removed
584 C = clean
584 C = clean
585 ! = missing (deleted by non-hg command, but still tracked)
585 ! = missing (deleted by non-hg command, but still tracked)
586 ? = not tracked
586 ? = not tracked
587 I = ignored
587 I = ignored
588 = origin of the previous file (with --copies)
588 = origin of the previous file (with --copies)
589
589
590 Returns 0 on success.
590 Returns 0 on success.
591
591
592 options ([+] can be repeated):
592 options ([+] can be repeated):
593
593
594 -A --all show status of all files
594 -A --all show status of all files
595 -m --modified show only modified files
595 -m --modified show only modified files
596 -a --added show only added files
596 -a --added show only added files
597 -r --removed show only removed files
597 -r --removed show only removed files
598 -d --deleted show only deleted (but tracked) files
598 -d --deleted show only deleted (but tracked) files
599 -c --clean show only files without changes
599 -c --clean show only files without changes
600 -u --unknown show only unknown (not tracked) files
600 -u --unknown show only unknown (not tracked) files
601 -i --ignored show only ignored files
601 -i --ignored show only ignored files
602 -n --no-status hide status prefix
602 -n --no-status hide status prefix
603 -C --copies show source of copied files
603 -C --copies show source of copied files
604 -0 --print0 end filenames with NUL, for use with xargs
604 -0 --print0 end filenames with NUL, for use with xargs
605 --rev REV [+] show difference from revision
605 --rev REV [+] show difference from revision
606 --change REV list the changed files of a revision
606 --change REV list the changed files of a revision
607 -I --include PATTERN [+] include names matching the given patterns
607 -I --include PATTERN [+] include names matching the given patterns
608 -X --exclude PATTERN [+] exclude names matching the given patterns
608 -X --exclude PATTERN [+] exclude names matching the given patterns
609 -S --subrepos recurse into subrepositories
609 -S --subrepos recurse into subrepositories
610
610
611 (some details hidden, use --verbose to show complete help)
611 (some details hidden, use --verbose to show complete help)
612
612
613 $ hg -q help status
613 $ hg -q help status
614 hg status [OPTION]... [FILE]...
614 hg status [OPTION]... [FILE]...
615
615
616 show changed files in the working directory
616 show changed files in the working directory
617
617
618 $ hg help foo
618 $ hg help foo
619 abort: no such help topic: foo
619 abort: no such help topic: foo
620 (try 'hg help --keyword foo')
620 (try 'hg help --keyword foo')
621 [255]
621 [255]
622
622
623 $ hg skjdfks
623 $ hg skjdfks
624 hg: unknown command 'skjdfks'
624 hg: unknown command 'skjdfks'
625 Mercurial Distributed SCM
625 Mercurial Distributed SCM
626
626
627 basic commands:
627 basic commands:
628
628
629 add add the specified files on the next commit
629 add add the specified files on the next commit
630 annotate show changeset information by line for each file
630 annotate show changeset information by line for each file
631 clone make a copy of an existing repository
631 clone make a copy of an existing repository
632 commit commit the specified files or all outstanding changes
632 commit commit the specified files or all outstanding changes
633 diff diff repository (or selected files)
633 diff diff repository (or selected files)
634 export dump the header and diffs for one or more changesets
634 export dump the header and diffs for one or more changesets
635 forget forget the specified files on the next commit
635 forget forget the specified files on the next commit
636 init create a new repository in the given directory
636 init create a new repository in the given directory
637 log show revision history of entire repository or files
637 log show revision history of entire repository or files
638 merge merge another revision into working directory
638 merge merge another revision into working directory
639 pull pull changes from the specified source
639 pull pull changes from the specified source
640 push push changes to the specified destination
640 push push changes to the specified destination
641 remove remove the specified files on the next commit
641 remove remove the specified files on the next commit
642 serve start stand-alone webserver
642 serve start stand-alone webserver
643 status show changed files in the working directory
643 status show changed files in the working directory
644 summary summarize working directory state
644 summary summarize working directory state
645 update update working directory (or switch revisions)
645 update update working directory (or switch revisions)
646
646
647 (use 'hg help' for the full list of commands or 'hg -v' for details)
647 (use 'hg help' for the full list of commands or 'hg -v' for details)
648 [255]
648 [255]
649
649
650
650
651 Make sure that we don't run afoul of the help system thinking that
651 Make sure that we don't run afoul of the help system thinking that
652 this is a section and erroring out weirdly.
652 this is a section and erroring out weirdly.
653
653
654 $ hg .log
654 $ hg .log
655 hg: unknown command '.log'
655 hg: unknown command '.log'
656 (did you mean log?)
656 (did you mean log?)
657 [255]
657 [255]
658
658
659 $ hg log.
659 $ hg log.
660 hg: unknown command 'log.'
660 hg: unknown command 'log.'
661 (did you mean log?)
661 (did you mean log?)
662 [255]
662 [255]
663 $ hg pu.lh
663 $ hg pu.lh
664 hg: unknown command 'pu.lh'
664 hg: unknown command 'pu.lh'
665 (did you mean one of pull, push?)
665 (did you mean one of pull, push?)
666 [255]
666 [255]
667
667
668 $ cat > helpext.py <<EOF
668 $ cat > helpext.py <<EOF
669 > import os
669 > import os
670 > from mercurial import cmdutil, commands
670 > from mercurial import cmdutil, commands
671 >
671 >
672 > cmdtable = {}
672 > cmdtable = {}
673 > command = cmdutil.command(cmdtable)
673 > command = cmdutil.command(cmdtable)
674 >
674 >
675 > @command('nohelp',
675 > @command('nohelp',
676 > [('', 'longdesc', 3, 'x'*90),
676 > [('', 'longdesc', 3, 'x'*90),
677 > ('n', '', None, 'normal desc'),
677 > ('n', '', None, 'normal desc'),
678 > ('', 'newline', '', 'line1\nline2')],
678 > ('', 'newline', '', 'line1\nline2')],
679 > 'hg nohelp',
679 > 'hg nohelp',
680 > norepo=True)
680 > norepo=True)
681 > @command('debugoptDEP', [('', 'dopt', None, 'option is (DEPRECATED)')])
681 > @command('debugoptDEP', [('', 'dopt', None, 'option is (DEPRECATED)')])
682 > @command('debugoptEXP', [('', 'eopt', None, 'option is (EXPERIMENTAL)')])
682 > @command('debugoptEXP', [('', 'eopt', None, 'option is (EXPERIMENTAL)')])
683 > def nohelp(ui, *args, **kwargs):
683 > def nohelp(ui, *args, **kwargs):
684 > pass
684 > pass
685 >
685 >
686 > def uisetup(ui):
686 > def uisetup(ui):
687 > ui.setconfig('alias', 'shellalias', '!echo hi', 'helpext')
687 > ui.setconfig('alias', 'shellalias', '!echo hi', 'helpext')
688 > ui.setconfig('alias', 'hgalias', 'summary', 'helpext')
688 > ui.setconfig('alias', 'hgalias', 'summary', 'helpext')
689 >
689 >
690 > EOF
690 > EOF
691 $ echo '[extensions]' >> $HGRCPATH
691 $ echo '[extensions]' >> $HGRCPATH
692 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
692 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
693
693
694 Test for aliases
694 Test for aliases
695
695
696 $ hg help hgalias
696 $ hg help hgalias
697 hg hgalias [--remote]
697 hg hgalias [--remote]
698
698
699 alias for: hg summary
699 alias for: hg summary
700
700
701 summarize working directory state
701 summarize working directory state
702
702
703 This generates a brief summary of the working directory state, including
703 This generates a brief summary of the working directory state, including
704 parents, branch, commit status, phase and available updates.
704 parents, branch, commit status, phase and available updates.
705
705
706 With the --remote option, this will check the default paths for incoming
706 With the --remote option, this will check the default paths for incoming
707 and outgoing changes. This can be time-consuming.
707 and outgoing changes. This can be time-consuming.
708
708
709 Returns 0 on success.
709 Returns 0 on success.
710
710
711 defined by: helpext
711 defined by: helpext
712
712
713 options:
713 options:
714
714
715 --remote check for push and pull
715 --remote check for push and pull
716
716
717 (some details hidden, use --verbose to show complete help)
717 (some details hidden, use --verbose to show complete help)
718
718
719 $ hg help shellalias
719 $ hg help shellalias
720 hg shellalias
720 hg shellalias
721
721
722 shell alias for:
722 shell alias for:
723
723
724 echo hi
724 echo hi
725
725
726 defined by: helpext
726 defined by: helpext
727
727
728 (some details hidden, use --verbose to show complete help)
728 (some details hidden, use --verbose to show complete help)
729
729
730 Test command with no help text
730 Test command with no help text
731
731
732 $ hg help nohelp
732 $ hg help nohelp
733 hg nohelp
733 hg nohelp
734
734
735 (no help text available)
735 (no help text available)
736
736
737 options:
737 options:
738
738
739 --longdesc VALUE xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
739 --longdesc VALUE xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
740 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (default: 3)
740 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (default: 3)
741 -n -- normal desc
741 -n -- normal desc
742 --newline VALUE line1 line2
742 --newline VALUE line1 line2
743
743
744 (some details hidden, use --verbose to show complete help)
744 (some details hidden, use --verbose to show complete help)
745
745
746 $ hg help -k nohelp
746 $ hg help -k nohelp
747 Commands:
747 Commands:
748
748
749 nohelp hg nohelp
749 nohelp hg nohelp
750
750
751 Extension Commands:
751 Extension Commands:
752
752
753 nohelp (no help text available)
753 nohelp (no help text available)
754
754
755 Test that default list of commands omits extension commands
755 Test that default list of commands omits extension commands
756
756
757 $ hg help
757 $ hg help
758 Mercurial Distributed SCM
758 Mercurial Distributed SCM
759
759
760 list of commands:
760 list of commands:
761
761
762 add add the specified files on the next commit
762 add add the specified files on the next commit
763 addremove add all new files, delete all missing files
763 addremove add all new files, delete all missing files
764 annotate show changeset information by line for each file
764 annotate show changeset information by line for each file
765 archive create an unversioned archive of a repository revision
765 archive create an unversioned archive of a repository revision
766 backout reverse effect of earlier changeset
766 backout reverse effect of earlier changeset
767 bisect subdivision search of changesets
767 bisect subdivision search of changesets
768 bookmarks create a new bookmark or list existing bookmarks
768 bookmarks create a new bookmark or list existing bookmarks
769 branch set or show the current branch name
769 branch set or show the current branch name
770 branches list repository named branches
770 branches list repository named branches
771 bundle create a changegroup file
771 bundle create a changegroup file
772 cat output the current or given revision of files
772 cat output the current or given revision of files
773 clone make a copy of an existing repository
773 clone make a copy of an existing repository
774 commit commit the specified files or all outstanding changes
774 commit commit the specified files or all outstanding changes
775 config show combined config settings from all hgrc files
775 config show combined config settings from all hgrc files
776 copy mark files as copied for the next commit
776 copy mark files as copied for the next commit
777 diff diff repository (or selected files)
777 diff diff repository (or selected files)
778 export dump the header and diffs for one or more changesets
778 export dump the header and diffs for one or more changesets
779 files list tracked files
779 files list tracked files
780 forget forget the specified files on the next commit
780 forget forget the specified files on the next commit
781 graft copy changes from other branches onto the current branch
781 graft copy changes from other branches onto the current branch
782 grep search revision history for a pattern in specified files
782 grep search revision history for a pattern in specified files
783 heads show branch heads
783 heads show branch heads
784 help show help for a given topic or a help overview
784 help show help for a given topic or a help overview
785 identify identify the working directory or specified revision
785 identify identify the working directory or specified revision
786 import import an ordered set of patches
786 import import an ordered set of patches
787 incoming show new changesets found in source
787 incoming show new changesets found in source
788 init create a new repository in the given directory
788 init create a new repository in the given directory
789 log show revision history of entire repository or files
789 log show revision history of entire repository or files
790 manifest output the current or given revision of the project manifest
790 manifest output the current or given revision of the project manifest
791 merge merge another revision into working directory
791 merge merge another revision into working directory
792 outgoing show changesets not found in the destination
792 outgoing show changesets not found in the destination
793 paths show aliases for remote repositories
793 paths show aliases for remote repositories
794 phase set or show the current phase name
794 phase set or show the current phase name
795 pull pull changes from the specified source
795 pull pull changes from the specified source
796 push push changes to the specified destination
796 push push changes to the specified destination
797 recover roll back an interrupted transaction
797 recover roll back an interrupted transaction
798 remove remove the specified files on the next commit
798 remove remove the specified files on the next commit
799 rename rename files; equivalent of copy + remove
799 rename rename files; equivalent of copy + remove
800 resolve redo merges or set/view the merge status of files
800 resolve redo merges or set/view the merge status of files
801 revert restore files to their checkout state
801 revert restore files to their checkout state
802 root print the root (top) of the current working directory
802 root print the root (top) of the current working directory
803 serve start stand-alone webserver
803 serve start stand-alone webserver
804 status show changed files in the working directory
804 status show changed files in the working directory
805 summary summarize working directory state
805 summary summarize working directory state
806 tag add one or more tags for the current or given revision
806 tag add one or more tags for the current or given revision
807 tags list repository tags
807 tags list repository tags
808 unbundle apply one or more changegroup files
808 unbundle apply one or more changegroup files
809 update update working directory (or switch revisions)
809 update update working directory (or switch revisions)
810 verify verify the integrity of the repository
810 verify verify the integrity of the repository
811 version output version and copyright information
811 version output version and copyright information
812
812
813 enabled extensions:
813 enabled extensions:
814
814
815 helpext (no help text available)
815 helpext (no help text available)
816
816
817 additional help topics:
817 additional help topics:
818
818
819 config Configuration Files
819 config Configuration Files
820 dates Date Formats
820 dates Date Formats
821 diffs Diff Formats
821 diffs Diff Formats
822 environment Environment Variables
822 environment Environment Variables
823 extensions Using Additional Features
823 extensions Using Additional Features
824 filesets Specifying File Sets
824 filesets Specifying File Sets
825 glossary Glossary
825 glossary Glossary
826 hgignore Syntax for Mercurial Ignore Files
826 hgignore Syntax for Mercurial Ignore Files
827 hgweb Configuring hgweb
827 hgweb Configuring hgweb
828 internals Technical implementation topics
828 internals Technical implementation topics
829 merge-tools Merge Tools
829 merge-tools Merge Tools
830 patterns File Name Patterns
830 patterns File Name Patterns
831 phases Working with Phases
831 phases Working with Phases
832 revisions Specifying Revisions
832 revisions Specifying Revisions
833 scripting Using Mercurial from scripts and automation
833 scripting Using Mercurial from scripts and automation
834 subrepos Subrepositories
834 subrepos Subrepositories
835 templating Template Usage
835 templating Template Usage
836 urls URL Paths
836 urls URL Paths
837
837
838 (use 'hg help -v' to show built-in aliases and global options)
838 (use 'hg help -v' to show built-in aliases and global options)
839
839
840
840
841 Test list of internal help commands
841 Test list of internal help commands
842
842
843 $ hg help debug
843 $ hg help debug
844 debug commands (internal and unsupported):
844 debug commands (internal and unsupported):
845
845
846 debugancestor
846 debugancestor
847 find the ancestor revision of two revisions in a given index
847 find the ancestor revision of two revisions in a given index
848 debugapplystreamclonebundle
848 debugapplystreamclonebundle
849 apply a stream clone bundle file
849 apply a stream clone bundle file
850 debugbuilddag
850 debugbuilddag
851 builds a repo with a given DAG from scratch in the current
851 builds a repo with a given DAG from scratch in the current
852 empty repo
852 empty repo
853 debugbundle lists the contents of a bundle
853 debugbundle lists the contents of a bundle
854 debugcheckstate
854 debugcheckstate
855 validate the correctness of the current dirstate
855 validate the correctness of the current dirstate
856 debugcommands
856 debugcommands
857 list all available commands and options
857 list all available commands and options
858 debugcomplete
858 debugcomplete
859 returns the completion list associated with the given command
859 returns the completion list associated with the given command
860 debugcreatestreamclonebundle
860 debugcreatestreamclonebundle
861 create a stream clone bundle file
861 create a stream clone bundle file
862 debugdag format the changelog or an index DAG as a concise textual
862 debugdag format the changelog or an index DAG as a concise textual
863 description
863 description
864 debugdata dump the contents of a data file revision
864 debugdata dump the contents of a data file revision
865 debugdate parse and display a date
865 debugdate parse and display a date
866 debugdeltachain
866 debugdeltachain
867 dump information about delta chains in a revlog
867 dump information about delta chains in a revlog
868 debugdirstate
868 debugdirstate
869 show the contents of the current dirstate
869 show the contents of the current dirstate
870 debugdiscovery
870 debugdiscovery
871 runs the changeset discovery protocol in isolation
871 runs the changeset discovery protocol in isolation
872 debugextensions
872 debugextensions
873 show information about active extensions
873 show information about active extensions
874 debugfileset parse and apply a fileset specification
874 debugfileset parse and apply a fileset specification
875 debugfsinfo show information detected about current filesystem
875 debugfsinfo show information detected about current filesystem
876 debuggetbundle
876 debuggetbundle
877 retrieves a bundle from a repo
877 retrieves a bundle from a repo
878 debugignore display the combined ignore pattern and information about
878 debugignore display the combined ignore pattern and information about
879 ignored files
879 ignored files
880 debugindex dump the contents of an index file
880 debugindex dump the contents of an index file
881 debugindexdot
881 debugindexdot
882 dump an index DAG as a graphviz dot file
882 dump an index DAG as a graphviz dot file
883 debuginstall test Mercurial installation
883 debuginstall test Mercurial installation
884 debugknown test whether node ids are known to a repo
884 debugknown test whether node ids are known to a repo
885 debuglocks show or modify state of locks
885 debuglocks show or modify state of locks
886 debugmergestate
886 debugmergestate
887 print merge state
887 print merge state
888 debugnamecomplete
888 debugnamecomplete
889 complete "names" - tags, open branch names, bookmark names
889 complete "names" - tags, open branch names, bookmark names
890 debugobsolete
890 debugobsolete
891 create arbitrary obsolete marker
891 create arbitrary obsolete marker
892 debugoptDEP (no help text available)
892 debugoptDEP (no help text available)
893 debugoptEXP (no help text available)
893 debugoptEXP (no help text available)
894 debugpathcomplete
894 debugpathcomplete
895 complete part or all of a tracked path
895 complete part or all of a tracked path
896 debugpushkey access the pushkey key/value protocol
896 debugpushkey access the pushkey key/value protocol
897 debugpvec (no help text available)
897 debugpvec (no help text available)
898 debugrebuilddirstate
898 debugrebuilddirstate
899 rebuild the dirstate as it would look like for the given
899 rebuild the dirstate as it would look like for the given
900 revision
900 revision
901 debugrebuildfncache
901 debugrebuildfncache
902 rebuild the fncache file
902 rebuild the fncache file
903 debugrename dump rename information
903 debugrename dump rename information
904 debugrevlog show data and statistics about a revlog
904 debugrevlog show data and statistics about a revlog
905 debugrevspec parse and apply a revision specification
905 debugrevspec parse and apply a revision specification
906 debugsetparents
906 debugsetparents
907 manually set the parents of the current working directory
907 manually set the parents of the current working directory
908 debugsub (no help text available)
908 debugsub (no help text available)
909 debugsuccessorssets
909 debugsuccessorssets
910 show set of successors for revision
910 show set of successors for revision
911 debugtemplate
911 debugtemplate
912 parse and apply a template
912 parse and apply a template
913 debugupgraderepo
913 debugupgraderepo
914 upgrade a repository to use different features
914 upgrade a repository to use different features
915 debugwalk show how files match on given patterns
915 debugwalk show how files match on given patterns
916 debugwireargs
916 debugwireargs
917 (no help text available)
917 (no help text available)
918
918
919 (use 'hg help -v debug' to show built-in aliases and global options)
919 (use 'hg help -v debug' to show built-in aliases and global options)
920
920
921 internals topic renders index of available sub-topics
921 internals topic renders index of available sub-topics
922
922
923 $ hg help internals
923 $ hg help internals
924 Technical implementation topics
924 Technical implementation topics
925 """""""""""""""""""""""""""""""
925 """""""""""""""""""""""""""""""
926
926
927 bundles Bundles
927 bundles Bundles
928 changegroups Changegroups
928 changegroups Changegroups
929 requirements Repository Requirements
929 requirements Repository Requirements
930 revlogs Revision Logs
930 revlogs Revision Logs
931 wireprotocol Wire Protocol
931 wireprotocol Wire Protocol
932
932
933 sub-topics can be accessed
933 sub-topics can be accessed
934
934
935 $ hg help internals.changegroups
935 $ hg help internals.changegroups
936 Changegroups
936 Changegroups
937 """"""""""""
937 """"""""""""
938
938
939 Changegroups are representations of repository revlog data, specifically
939 Changegroups are representations of repository revlog data, specifically
940 the changelog, manifest, and filelogs.
940 the changelog, manifest, and filelogs.
941
941
942 There are 3 versions of changegroups: "1", "2", and "3". From a high-
942 There are 3 versions of changegroups: "1", "2", and "3". From a high-
943 level, versions "1" and "2" are almost exactly the same, with the only
943 level, versions "1" and "2" are almost exactly the same, with the only
944 difference being a header on entries in the changeset segment. Version "3"
944 difference being a header on entries in the changeset segment. Version "3"
945 adds support for exchanging treemanifests and includes revlog flags in the
945 adds support for exchanging treemanifests and includes revlog flags in the
946 delta header.
946 delta header.
947
947
948 Changegroups consists of 3 logical segments:
948 Changegroups consists of 3 logical segments:
949
949
950 +---------------------------------+
950 +---------------------------------+
951 | | | |
951 | | | |
952 | changeset | manifest | filelogs |
952 | changeset | manifest | filelogs |
953 | | | |
953 | | | |
954 +---------------------------------+
954 +---------------------------------+
955
955
956 The principle building block of each segment is a *chunk*. A *chunk* is a
956 The principle building block of each segment is a *chunk*. A *chunk* is a
957 framed piece of data:
957 framed piece of data:
958
958
959 +---------------------------------------+
959 +---------------------------------------+
960 | | |
960 | | |
961 | length | data |
961 | length | data |
962 | (32 bits) | <length> bytes |
962 | (32 bits) | <length> bytes |
963 | | |
963 | | |
964 +---------------------------------------+
964 +---------------------------------------+
965
965
966 Each chunk starts with a 32-bit big-endian signed integer indicating the
966 Each chunk starts with a 32-bit big-endian signed integer indicating the
967 length of the raw data that follows.
967 length of the raw data that follows.
968
968
969 There is a special case chunk that has 0 length ("0x00000000"). We call
969 There is a special case chunk that has 0 length ("0x00000000"). We call
970 this an *empty chunk*.
970 this an *empty chunk*.
971
971
972 Delta Groups
972 Delta Groups
973 ============
973 ============
974
974
975 A *delta group* expresses the content of a revlog as a series of deltas,
975 A *delta group* expresses the content of a revlog as a series of deltas,
976 or patches against previous revisions.
976 or patches against previous revisions.
977
977
978 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
978 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
979 to signal the end of the delta group:
979 to signal the end of the delta group:
980
980
981 +------------------------------------------------------------------------+
981 +------------------------------------------------------------------------+
982 | | | | | |
982 | | | | | |
983 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
983 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
984 | (32 bits) | (various) | (32 bits) | (various) | (32 bits) |
984 | (32 bits) | (various) | (32 bits) | (various) | (32 bits) |
985 | | | | | |
985 | | | | | |
986 +------------------------------------------------------------+-----------+
986 +------------------------------------------------------------+-----------+
987
987
988 Each *chunk*'s data consists of the following:
988 Each *chunk*'s data consists of the following:
989
989
990 +-----------------------------------------+
990 +-----------------------------------------+
991 | | | |
991 | | | |
992 | delta header | mdiff header | delta |
992 | delta header | mdiff header | delta |
993 | (various) | (12 bytes) | (various) |
993 | (various) | (12 bytes) | (various) |
994 | | | |
994 | | | |
995 +-----------------------------------------+
995 +-----------------------------------------+
996
996
997 The *length* field is the byte length of the remaining 3 logical pieces of
997 The *length* field is the byte length of the remaining 3 logical pieces of
998 data. The *delta* is a diff from an existing entry in the changelog.
998 data. The *delta* is a diff from an existing entry in the changelog.
999
999
1000 The *delta header* is different between versions "1", "2", and "3" of the
1000 The *delta header* is different between versions "1", "2", and "3" of the
1001 changegroup format.
1001 changegroup format.
1002
1002
1003 Version 1:
1003 Version 1:
1004
1004
1005 +------------------------------------------------------+
1005 +------------------------------------------------------+
1006 | | | | |
1006 | | | | |
1007 | node | p1 node | p2 node | link node |
1007 | node | p1 node | p2 node | link node |
1008 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1008 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1009 | | | | |
1009 | | | | |
1010 +------------------------------------------------------+
1010 +------------------------------------------------------+
1011
1011
1012 Version 2:
1012 Version 2:
1013
1013
1014 +------------------------------------------------------------------+
1014 +------------------------------------------------------------------+
1015 | | | | | |
1015 | | | | | |
1016 | node | p1 node | p2 node | base node | link node |
1016 | node | p1 node | p2 node | base node | link node |
1017 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1017 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1018 | | | | | |
1018 | | | | | |
1019 +------------------------------------------------------------------+
1019 +------------------------------------------------------------------+
1020
1020
1021 Version 3:
1021 Version 3:
1022
1022
1023 +------------------------------------------------------------------------------+
1023 +------------------------------------------------------------------------------+
1024 | | | | | | |
1024 | | | | | | |
1025 | node | p1 node | p2 node | base node | link node | flags |
1025 | node | p1 node | p2 node | base node | link node | flags |
1026 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
1026 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
1027 | | | | | | |
1027 | | | | | | |
1028 +------------------------------------------------------------------------------+
1028 +------------------------------------------------------------------------------+
1029
1029
1030 The *mdiff header* consists of 3 32-bit big-endian signed integers
1030 The *mdiff header* consists of 3 32-bit big-endian signed integers
1031 describing offsets at which to apply the following delta content:
1031 describing offsets at which to apply the following delta content:
1032
1032
1033 +-------------------------------------+
1033 +-------------------------------------+
1034 | | | |
1034 | | | |
1035 | offset | old length | new length |
1035 | offset | old length | new length |
1036 | (32 bits) | (32 bits) | (32 bits) |
1036 | (32 bits) | (32 bits) | (32 bits) |
1037 | | | |
1037 | | | |
1038 +-------------------------------------+
1038 +-------------------------------------+
1039
1039
1040 In version 1, the delta is always applied against the previous node from
1040 In version 1, the delta is always applied against the previous node from
1041 the changegroup or the first parent if this is the first entry in the
1041 the changegroup or the first parent if this is the first entry in the
1042 changegroup.
1042 changegroup.
1043
1043
1044 In version 2, the delta base node is encoded in the entry in the
1044 In version 2, the delta base node is encoded in the entry in the
1045 changegroup. This allows the delta to be expressed against any parent,
1045 changegroup. This allows the delta to be expressed against any parent,
1046 which can result in smaller deltas and more efficient encoding of data.
1046 which can result in smaller deltas and more efficient encoding of data.
1047
1047
1048 Changeset Segment
1048 Changeset Segment
1049 =================
1049 =================
1050
1050
1051 The *changeset segment* consists of a single *delta group* holding
1051 The *changeset segment* consists of a single *delta group* holding
1052 changelog data. It is followed by an *empty chunk* to denote the boundary
1052 changelog data. It is followed by an *empty chunk* to denote the boundary
1053 to the *manifests segment*.
1053 to the *manifests segment*.
1054
1054
1055 Manifest Segment
1055 Manifest Segment
1056 ================
1056 ================
1057
1057
1058 The *manifest segment* consists of a single *delta group* holding manifest
1058 The *manifest segment* consists of a single *delta group* holding manifest
1059 data. It is followed by an *empty chunk* to denote the boundary to the
1059 data. It is followed by an *empty chunk* to denote the boundary to the
1060 *filelogs segment*.
1060 *filelogs segment*.
1061
1061
1062 Filelogs Segment
1062 Filelogs Segment
1063 ================
1063 ================
1064
1064
1065 The *filelogs* segment consists of multiple sub-segments, each
1065 The *filelogs* segment consists of multiple sub-segments, each
1066 corresponding to an individual file whose data is being described:
1066 corresponding to an individual file whose data is being described:
1067
1067
1068 +--------------------------------------+
1068 +--------------------------------------+
1069 | | | | |
1069 | | | | |
1070 | filelog0 | filelog1 | filelog2 | ... |
1070 | filelog0 | filelog1 | filelog2 | ... |
1071 | | | | |
1071 | | | | |
1072 +--------------------------------------+
1072 +--------------------------------------+
1073
1073
1074 In version "3" of the changegroup format, filelogs may include directory
1074 In version "3" of the changegroup format, filelogs may include directory
1075 logs when treemanifests are in use. directory logs are identified by
1075 logs when treemanifests are in use. directory logs are identified by
1076 having a trailing '/' on their filename (see below).
1076 having a trailing '/' on their filename (see below).
1077
1077
1078 The final filelog sub-segment is followed by an *empty chunk* to denote
1078 The final filelog sub-segment is followed by an *empty chunk* to denote
1079 the end of the segment and the overall changegroup.
1079 the end of the segment and the overall changegroup.
1080
1080
1081 Each filelog sub-segment consists of the following:
1081 Each filelog sub-segment consists of the following:
1082
1082
1083 +------------------------------------------+
1083 +------------------------------------------+
1084 | | | |
1084 | | | |
1085 | filename size | filename | delta group |
1085 | filename size | filename | delta group |
1086 | (32 bits) | (various) | (various) |
1086 | (32 bits) | (various) | (various) |
1087 | | | |
1087 | | | |
1088 +------------------------------------------+
1088 +------------------------------------------+
1089
1089
1090 That is, a *chunk* consisting of the filename (not terminated or padded)
1090 That is, a *chunk* consisting of the filename (not terminated or padded)
1091 followed by N chunks constituting the *delta group* for this file.
1091 followed by N chunks constituting the *delta group* for this file.
1092
1092
1093 Test list of commands with command with no help text
1093 Test list of commands with command with no help text
1094
1094
1095 $ hg help helpext
1095 $ hg help helpext
1096 helpext extension - no help text available
1096 helpext extension - no help text available
1097
1097
1098 list of commands:
1098 list of commands:
1099
1099
1100 nohelp (no help text available)
1100 nohelp (no help text available)
1101
1101
1102 (use 'hg help -v helpext' to show built-in aliases and global options)
1102 (use 'hg help -v helpext' to show built-in aliases and global options)
1103
1103
1104
1104
1105 test deprecated and experimental options are hidden in command help
1105 test deprecated and experimental options are hidden in command help
1106 $ hg help debugoptDEP
1106 $ hg help debugoptDEP
1107 hg debugoptDEP
1107 hg debugoptDEP
1108
1108
1109 (no help text available)
1109 (no help text available)
1110
1110
1111 options:
1111 options:
1112
1112
1113 (some details hidden, use --verbose to show complete help)
1113 (some details hidden, use --verbose to show complete help)
1114
1114
1115 $ hg help debugoptEXP
1115 $ hg help debugoptEXP
1116 hg debugoptEXP
1116 hg debugoptEXP
1117
1117
1118 (no help text available)
1118 (no help text available)
1119
1119
1120 options:
1120 options:
1121
1121
1122 (some details hidden, use --verbose to show complete help)
1122 (some details hidden, use --verbose to show complete help)
1123
1123
1124 test deprecated and experimental options is shown with -v
1124 test deprecated and experimental options is shown with -v
1125 $ hg help -v debugoptDEP | grep dopt
1125 $ hg help -v debugoptDEP | grep dopt
1126 --dopt option is (DEPRECATED)
1126 --dopt option is (DEPRECATED)
1127 $ hg help -v debugoptEXP | grep eopt
1127 $ hg help -v debugoptEXP | grep eopt
1128 --eopt option is (EXPERIMENTAL)
1128 --eopt option is (EXPERIMENTAL)
1129
1129
1130 #if gettext
1130 #if gettext
1131 test deprecated option is hidden with translation with untranslated description
1131 test deprecated option is hidden with translation with untranslated description
1132 (use many globy for not failing on changed transaction)
1132 (use many globy for not failing on changed transaction)
1133 $ LANGUAGE=sv hg help debugoptDEP
1133 $ LANGUAGE=sv hg help debugoptDEP
1134 hg debugoptDEP
1134 hg debugoptDEP
1135
1135
1136 (*) (glob)
1136 (*) (glob)
1137
1137
1138 options:
1138 options:
1139
1139
1140 (some details hidden, use --verbose to show complete help)
1140 (some details hidden, use --verbose to show complete help)
1141 #endif
1141 #endif
1142
1142
1143 Test commands that collide with topics (issue4240)
1143 Test commands that collide with topics (issue4240)
1144
1144
1145 $ hg config -hq
1145 $ hg config -hq
1146 hg config [-u] [NAME]...
1146 hg config [-u] [NAME]...
1147
1147
1148 show combined config settings from all hgrc files
1148 show combined config settings from all hgrc files
1149 $ hg showconfig -hq
1149 $ hg showconfig -hq
1150 hg config [-u] [NAME]...
1150 hg config [-u] [NAME]...
1151
1151
1152 show combined config settings from all hgrc files
1152 show combined config settings from all hgrc files
1153
1153
1154 Test a help topic
1154 Test a help topic
1155
1155
1156 $ hg help dates
1156 $ hg help dates
1157 Date Formats
1157 Date Formats
1158 """"""""""""
1158 """"""""""""
1159
1159
1160 Some commands allow the user to specify a date, e.g.:
1160 Some commands allow the user to specify a date, e.g.:
1161
1161
1162 - backout, commit, import, tag: Specify the commit date.
1162 - backout, commit, import, tag: Specify the commit date.
1163 - log, revert, update: Select revision(s) by date.
1163 - log, revert, update: Select revision(s) by date.
1164
1164
1165 Many date formats are valid. Here are some examples:
1165 Many date formats are valid. Here are some examples:
1166
1166
1167 - "Wed Dec 6 13:18:29 2006" (local timezone assumed)
1167 - "Wed Dec 6 13:18:29 2006" (local timezone assumed)
1168 - "Dec 6 13:18 -0600" (year assumed, time offset provided)
1168 - "Dec 6 13:18 -0600" (year assumed, time offset provided)
1169 - "Dec 6 13:18 UTC" (UTC and GMT are aliases for +0000)
1169 - "Dec 6 13:18 UTC" (UTC and GMT are aliases for +0000)
1170 - "Dec 6" (midnight)
1170 - "Dec 6" (midnight)
1171 - "13:18" (today assumed)
1171 - "13:18" (today assumed)
1172 - "3:39" (3:39AM assumed)
1172 - "3:39" (3:39AM assumed)
1173 - "3:39pm" (15:39)
1173 - "3:39pm" (15:39)
1174 - "2006-12-06 13:18:29" (ISO 8601 format)
1174 - "2006-12-06 13:18:29" (ISO 8601 format)
1175 - "2006-12-6 13:18"
1175 - "2006-12-6 13:18"
1176 - "2006-12-6"
1176 - "2006-12-6"
1177 - "12-6"
1177 - "12-6"
1178 - "12/6"
1178 - "12/6"
1179 - "12/6/6" (Dec 6 2006)
1179 - "12/6/6" (Dec 6 2006)
1180 - "today" (midnight)
1180 - "today" (midnight)
1181 - "yesterday" (midnight)
1181 - "yesterday" (midnight)
1182 - "now" - right now
1182 - "now" - right now
1183
1183
1184 Lastly, there is Mercurial's internal format:
1184 Lastly, there is Mercurial's internal format:
1185
1185
1186 - "1165411109 0" (Wed Dec 6 13:18:29 2006 UTC)
1186 - "1165411109 0" (Wed Dec 6 13:18:29 2006 UTC)
1187
1187
1188 This is the internal representation format for dates. The first number is
1188 This is the internal representation format for dates. The first number is
1189 the number of seconds since the epoch (1970-01-01 00:00 UTC). The second
1189 the number of seconds since the epoch (1970-01-01 00:00 UTC). The second
1190 is the offset of the local timezone, in seconds west of UTC (negative if
1190 is the offset of the local timezone, in seconds west of UTC (negative if
1191 the timezone is east of UTC).
1191 the timezone is east of UTC).
1192
1192
1193 The log command also accepts date ranges:
1193 The log command also accepts date ranges:
1194
1194
1195 - "<DATE" - at or before a given date/time
1195 - "<DATE" - at or before a given date/time
1196 - ">DATE" - on or after a given date/time
1196 - ">DATE" - on or after a given date/time
1197 - "DATE to DATE" - a date range, inclusive
1197 - "DATE to DATE" - a date range, inclusive
1198 - "-DAYS" - within a given number of days of today
1198 - "-DAYS" - within a given number of days of today
1199
1199
1200 Test repeated config section name
1200 Test repeated config section name
1201
1201
1202 $ hg help config.host
1202 $ hg help config.host
1203 "http_proxy.host"
1203 "http_proxy.host"
1204 Host name and (optional) port of the proxy server, for example
1204 Host name and (optional) port of the proxy server, for example
1205 "myproxy:8000".
1205 "myproxy:8000".
1206
1206
1207 "smtp.host"
1207 "smtp.host"
1208 Host name of mail server, e.g. "mail.example.com".
1208 Host name of mail server, e.g. "mail.example.com".
1209
1209
1210 Unrelated trailing paragraphs shouldn't be included
1210 Unrelated trailing paragraphs shouldn't be included
1211
1211
1212 $ hg help config.extramsg | grep '^$'
1212 $ hg help config.extramsg | grep '^$'
1213
1213
1214
1214
1215 Test capitalized section name
1215 Test capitalized section name
1216
1216
1217 $ hg help scripting.HGPLAIN > /dev/null
1217 $ hg help scripting.HGPLAIN > /dev/null
1218
1218
1219 Help subsection:
1219 Help subsection:
1220
1220
1221 $ hg help config.charsets |grep "Email example:" > /dev/null
1221 $ hg help config.charsets |grep "Email example:" > /dev/null
1222 [1]
1222 [1]
1223
1223
1224 Show nested definitions
1224 Show nested definitions
1225 ("profiling.type"[break]"ls"[break]"stat"[break])
1225 ("profiling.type"[break]"ls"[break]"stat"[break])
1226
1226
1227 $ hg help config.type | egrep '^$'|wc -l
1227 $ hg help config.type | egrep '^$'|wc -l
1228 \s*3 (re)
1228 \s*3 (re)
1229
1229
1230 Separate sections from subsections
1230 Separate sections from subsections
1231
1231
1232 $ hg help config.format | egrep '^ ("|-)|^\s*$' | uniq
1232 $ hg help config.format | egrep '^ ("|-)|^\s*$' | uniq
1233 "format"
1233 "format"
1234 --------
1234 --------
1235
1235
1236 "usegeneraldelta"
1236 "usegeneraldelta"
1237
1237
1238 "dotencode"
1238 "dotencode"
1239
1239
1240 "usefncache"
1240 "usefncache"
1241
1241
1242 "usestore"
1242 "usestore"
1243
1243
1244 "profiling"
1244 "profiling"
1245 -----------
1245 -----------
1246
1246
1247 "format"
1247 "format"
1248
1248
1249 "progress"
1249 "progress"
1250 ----------
1250 ----------
1251
1251
1252 "format"
1252 "format"
1253
1253
1254
1254
1255 Last item in help config.*:
1255 Last item in help config.*:
1256
1256
1257 $ hg help config.`hg help config|grep '^ "'| \
1257 $ hg help config.`hg help config|grep '^ "'| \
1258 > tail -1|sed 's![ "]*!!g'`| \
1258 > tail -1|sed 's![ "]*!!g'`| \
1259 > grep 'hg help -c config' > /dev/null
1259 > grep 'hg help -c config' > /dev/null
1260 [1]
1260 [1]
1261
1261
1262 note to use help -c for general hg help config:
1262 note to use help -c for general hg help config:
1263
1263
1264 $ hg help config |grep 'hg help -c config' > /dev/null
1264 $ hg help config |grep 'hg help -c config' > /dev/null
1265
1265
1266 Test templating help
1266 Test templating help
1267
1267
1268 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
1268 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
1269 desc String. The text of the changeset description.
1269 desc String. The text of the changeset description.
1270 diffstat String. Statistics of changes with the following format:
1270 diffstat String. Statistics of changes with the following format:
1271 firstline Any text. Returns the first line of text.
1271 firstline Any text. Returns the first line of text.
1272 nonempty Any text. Returns '(none)' if the string is empty.
1272 nonempty Any text. Returns '(none)' if the string is empty.
1273
1273
1274 Test deprecated items
1274 Test deprecated items
1275
1275
1276 $ hg help -v templating | grep currentbookmark
1276 $ hg help -v templating | grep currentbookmark
1277 currentbookmark
1277 currentbookmark
1278 $ hg help templating | (grep currentbookmark || true)
1278 $ hg help templating | (grep currentbookmark || true)
1279
1279
1280 Test help hooks
1280 Test help hooks
1281
1281
1282 $ cat > helphook1.py <<EOF
1282 $ cat > helphook1.py <<EOF
1283 > from mercurial import help
1283 > from mercurial import help
1284 >
1284 >
1285 > def rewrite(ui, topic, doc):
1285 > def rewrite(ui, topic, doc):
1286 > return doc + '\nhelphook1\n'
1286 > return doc + '\nhelphook1\n'
1287 >
1287 >
1288 > def extsetup(ui):
1288 > def extsetup(ui):
1289 > help.addtopichook('revisions', rewrite)
1289 > help.addtopichook('revisions', rewrite)
1290 > EOF
1290 > EOF
1291 $ cat > helphook2.py <<EOF
1291 $ cat > helphook2.py <<EOF
1292 > from mercurial import help
1292 > from mercurial import help
1293 >
1293 >
1294 > def rewrite(ui, topic, doc):
1294 > def rewrite(ui, topic, doc):
1295 > return doc + '\nhelphook2\n'
1295 > return doc + '\nhelphook2\n'
1296 >
1296 >
1297 > def extsetup(ui):
1297 > def extsetup(ui):
1298 > help.addtopichook('revisions', rewrite)
1298 > help.addtopichook('revisions', rewrite)
1299 > EOF
1299 > EOF
1300 $ echo '[extensions]' >> $HGRCPATH
1300 $ echo '[extensions]' >> $HGRCPATH
1301 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
1301 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
1302 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
1302 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
1303 $ hg help revsets | grep helphook
1303 $ hg help revsets | grep helphook
1304 helphook1
1304 helphook1
1305 helphook2
1305 helphook2
1306
1306
1307 help -c should only show debug --debug
1307 help -c should only show debug --debug
1308
1308
1309 $ hg help -c --debug|egrep debug|wc -l|egrep '^\s*0\s*$'
1309 $ hg help -c --debug|egrep debug|wc -l|egrep '^\s*0\s*$'
1310 [1]
1310 [1]
1311
1311
1312 help -c should only show deprecated for -v
1312 help -c should only show deprecated for -v
1313
1313
1314 $ hg help -c -v|egrep DEPRECATED|wc -l|egrep '^\s*0\s*$'
1314 $ hg help -c -v|egrep DEPRECATED|wc -l|egrep '^\s*0\s*$'
1315 [1]
1315 [1]
1316
1316
1317 Test -s / --system
1317 Test -s / --system
1318
1318
1319 $ hg help config.files -s windows |grep 'etc/mercurial' | \
1319 $ hg help config.files -s windows |grep 'etc/mercurial' | \
1320 > wc -l | sed -e 's/ //g'
1320 > wc -l | sed -e 's/ //g'
1321 0
1321 0
1322 $ hg help config.files --system unix | grep 'USER' | \
1322 $ hg help config.files --system unix | grep 'USER' | \
1323 > wc -l | sed -e 's/ //g'
1323 > wc -l | sed -e 's/ //g'
1324 0
1324 0
1325
1325
1326 Test -e / -c / -k combinations
1326 Test -e / -c / -k combinations
1327
1327
1328 $ hg help -c|egrep '^[A-Z].*:|^ debug'
1328 $ hg help -c|egrep '^[A-Z].*:|^ debug'
1329 Commands:
1329 Commands:
1330 $ hg help -e|egrep '^[A-Z].*:|^ debug'
1330 $ hg help -e|egrep '^[A-Z].*:|^ debug'
1331 Extensions:
1331 Extensions:
1332 $ hg help -k|egrep '^[A-Z].*:|^ debug'
1332 $ hg help -k|egrep '^[A-Z].*:|^ debug'
1333 Topics:
1333 Topics:
1334 Commands:
1334 Commands:
1335 Extensions:
1335 Extensions:
1336 Extension Commands:
1336 Extension Commands:
1337 $ hg help -c schemes
1337 $ hg help -c schemes
1338 abort: no such help topic: schemes
1338 abort: no such help topic: schemes
1339 (try 'hg help --keyword schemes')
1339 (try 'hg help --keyword schemes')
1340 [255]
1340 [255]
1341 $ hg help -e schemes |head -1
1341 $ hg help -e schemes |head -1
1342 schemes extension - extend schemes with shortcuts to repository swarms
1342 schemes extension - extend schemes with shortcuts to repository swarms
1343 $ hg help -c -k dates |egrep '^(Topics|Extensions|Commands):'
1343 $ hg help -c -k dates |egrep '^(Topics|Extensions|Commands):'
1344 Commands:
1344 Commands:
1345 $ hg help -e -k a |egrep '^(Topics|Extensions|Commands):'
1345 $ hg help -e -k a |egrep '^(Topics|Extensions|Commands):'
1346 Extensions:
1346 Extensions:
1347 $ hg help -e -c -k date |egrep '^(Topics|Extensions|Commands):'
1347 $ hg help -e -c -k date |egrep '^(Topics|Extensions|Commands):'
1348 Extensions:
1348 Extensions:
1349 Commands:
1349 Commands:
1350 $ hg help -c commit > /dev/null
1350 $ hg help -c commit > /dev/null
1351 $ hg help -e -c commit > /dev/null
1351 $ hg help -e -c commit > /dev/null
1352 $ hg help -e commit > /dev/null
1352 $ hg help -e commit > /dev/null
1353 abort: no such help topic: commit
1353 abort: no such help topic: commit
1354 (try 'hg help --keyword commit')
1354 (try 'hg help --keyword commit')
1355 [255]
1355 [255]
1356
1356
1357 Test keyword search help
1357 Test keyword search help
1358
1358
1359 $ cat > prefixedname.py <<EOF
1359 $ cat > prefixedname.py <<EOF
1360 > '''matched against word "clone"
1360 > '''matched against word "clone"
1361 > '''
1361 > '''
1362 > EOF
1362 > EOF
1363 $ echo '[extensions]' >> $HGRCPATH
1363 $ echo '[extensions]' >> $HGRCPATH
1364 $ echo "dot.dot.prefixedname = `pwd`/prefixedname.py" >> $HGRCPATH
1364 $ echo "dot.dot.prefixedname = `pwd`/prefixedname.py" >> $HGRCPATH
1365 $ hg help -k clone
1365 $ hg help -k clone
1366 Topics:
1366 Topics:
1367
1367
1368 config Configuration Files
1368 config Configuration Files
1369 extensions Using Additional Features
1369 extensions Using Additional Features
1370 glossary Glossary
1370 glossary Glossary
1371 phases Working with Phases
1371 phases Working with Phases
1372 subrepos Subrepositories
1372 subrepos Subrepositories
1373 urls URL Paths
1373 urls URL Paths
1374
1374
1375 Commands:
1375 Commands:
1376
1376
1377 bookmarks create a new bookmark or list existing bookmarks
1377 bookmarks create a new bookmark or list existing bookmarks
1378 clone make a copy of an existing repository
1378 clone make a copy of an existing repository
1379 paths show aliases for remote repositories
1379 paths show aliases for remote repositories
1380 update update working directory (or switch revisions)
1380 update update working directory (or switch revisions)
1381
1381
1382 Extensions:
1382 Extensions:
1383
1383
1384 clonebundles advertise pre-generated bundles to seed clones
1384 clonebundles advertise pre-generated bundles to seed clones
1385 prefixedname matched against word "clone"
1385 prefixedname matched against word "clone"
1386 relink recreates hardlinks between repository clones
1386 relink recreates hardlinks between repository clones
1387
1387
1388 Extension Commands:
1388 Extension Commands:
1389
1389
1390 qclone clone main and patch repository at same time
1390 qclone clone main and patch repository at same time
1391
1391
1392 Test unfound topic
1392 Test unfound topic
1393
1393
1394 $ hg help nonexistingtopicthatwillneverexisteverever
1394 $ hg help nonexistingtopicthatwillneverexisteverever
1395 abort: no such help topic: nonexistingtopicthatwillneverexisteverever
1395 abort: no such help topic: nonexistingtopicthatwillneverexisteverever
1396 (try 'hg help --keyword nonexistingtopicthatwillneverexisteverever')
1396 (try 'hg help --keyword nonexistingtopicthatwillneverexisteverever')
1397 [255]
1397 [255]
1398
1398
1399 Test unfound keyword
1399 Test unfound keyword
1400
1400
1401 $ hg help --keyword nonexistingwordthatwillneverexisteverever
1401 $ hg help --keyword nonexistingwordthatwillneverexisteverever
1402 abort: no matches
1402 abort: no matches
1403 (try 'hg help' for a list of topics)
1403 (try 'hg help' for a list of topics)
1404 [255]
1404 [255]
1405
1405
1406 Test omit indicating for help
1406 Test omit indicating for help
1407
1407
1408 $ cat > addverboseitems.py <<EOF
1408 $ cat > addverboseitems.py <<EOF
1409 > '''extension to test omit indicating.
1409 > '''extension to test omit indicating.
1410 >
1410 >
1411 > This paragraph is never omitted (for extension)
1411 > This paragraph is never omitted (for extension)
1412 >
1412 >
1413 > .. container:: verbose
1413 > .. container:: verbose
1414 >
1414 >
1415 > This paragraph is omitted,
1415 > This paragraph is omitted,
1416 > if :hg:\`help\` is invoked without \`\`-v\`\` (for extension)
1416 > if :hg:\`help\` is invoked without \`\`-v\`\` (for extension)
1417 >
1417 >
1418 > This paragraph is never omitted, too (for extension)
1418 > This paragraph is never omitted, too (for extension)
1419 > '''
1419 > '''
1420 >
1420 >
1421 > from mercurial import help, commands
1421 > from mercurial import help, commands
1422 > testtopic = """This paragraph is never omitted (for topic).
1422 > testtopic = """This paragraph is never omitted (for topic).
1423 >
1423 >
1424 > .. container:: verbose
1424 > .. container:: verbose
1425 >
1425 >
1426 > This paragraph is omitted,
1426 > This paragraph is omitted,
1427 > if :hg:\`help\` is invoked without \`\`-v\`\` (for topic)
1427 > if :hg:\`help\` is invoked without \`\`-v\`\` (for topic)
1428 >
1428 >
1429 > This paragraph is never omitted, too (for topic)
1429 > This paragraph is never omitted, too (for topic)
1430 > """
1430 > """
1431 > def extsetup(ui):
1431 > def extsetup(ui):
1432 > help.helptable.append((["topic-containing-verbose"],
1432 > help.helptable.append((["topic-containing-verbose"],
1433 > "This is the topic to test omit indicating.",
1433 > "This is the topic to test omit indicating.",
1434 > lambda ui: testtopic))
1434 > lambda ui: testtopic))
1435 > EOF
1435 > EOF
1436 $ echo '[extensions]' >> $HGRCPATH
1436 $ echo '[extensions]' >> $HGRCPATH
1437 $ echo "addverboseitems = `pwd`/addverboseitems.py" >> $HGRCPATH
1437 $ echo "addverboseitems = `pwd`/addverboseitems.py" >> $HGRCPATH
1438 $ hg help addverboseitems
1438 $ hg help addverboseitems
1439 addverboseitems extension - extension to test omit indicating.
1439 addverboseitems extension - extension to test omit indicating.
1440
1440
1441 This paragraph is never omitted (for extension)
1441 This paragraph is never omitted (for extension)
1442
1442
1443 This paragraph is never omitted, too (for extension)
1443 This paragraph is never omitted, too (for extension)
1444
1444
1445 (some details hidden, use --verbose to show complete help)
1445 (some details hidden, use --verbose to show complete help)
1446
1446
1447 no commands defined
1447 no commands defined
1448 $ hg help -v addverboseitems
1448 $ hg help -v addverboseitems
1449 addverboseitems extension - extension to test omit indicating.
1449 addverboseitems extension - extension to test omit indicating.
1450
1450
1451 This paragraph is never omitted (for extension)
1451 This paragraph is never omitted (for extension)
1452
1452
1453 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1453 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1454 extension)
1454 extension)
1455
1455
1456 This paragraph is never omitted, too (for extension)
1456 This paragraph is never omitted, too (for extension)
1457
1457
1458 no commands defined
1458 no commands defined
1459 $ hg help topic-containing-verbose
1459 $ hg help topic-containing-verbose
1460 This is the topic to test omit indicating.
1460 This is the topic to test omit indicating.
1461 """"""""""""""""""""""""""""""""""""""""""
1461 """"""""""""""""""""""""""""""""""""""""""
1462
1462
1463 This paragraph is never omitted (for topic).
1463 This paragraph is never omitted (for topic).
1464
1464
1465 This paragraph is never omitted, too (for topic)
1465 This paragraph is never omitted, too (for topic)
1466
1466
1467 (some details hidden, use --verbose to show complete help)
1467 (some details hidden, use --verbose to show complete help)
1468 $ hg help -v topic-containing-verbose
1468 $ hg help -v topic-containing-verbose
1469 This is the topic to test omit indicating.
1469 This is the topic to test omit indicating.
1470 """"""""""""""""""""""""""""""""""""""""""
1470 """"""""""""""""""""""""""""""""""""""""""
1471
1471
1472 This paragraph is never omitted (for topic).
1472 This paragraph is never omitted (for topic).
1473
1473
1474 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1474 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1475 topic)
1475 topic)
1476
1476
1477 This paragraph is never omitted, too (for topic)
1477 This paragraph is never omitted, too (for topic)
1478
1478
1479 Test section lookup
1479 Test section lookup
1480
1480
1481 $ hg help revset.merge
1481 $ hg help revset.merge
1482 "merge()"
1482 "merge()"
1483 Changeset is a merge changeset.
1483 Changeset is a merge changeset.
1484
1484
1485 $ hg help glossary.dag
1485 $ hg help glossary.dag
1486 DAG
1486 DAG
1487 The repository of changesets of a distributed version control system
1487 The repository of changesets of a distributed version control system
1488 (DVCS) can be described as a directed acyclic graph (DAG), consisting
1488 (DVCS) can be described as a directed acyclic graph (DAG), consisting
1489 of nodes and edges, where nodes correspond to changesets and edges
1489 of nodes and edges, where nodes correspond to changesets and edges
1490 imply a parent -> child relation. This graph can be visualized by
1490 imply a parent -> child relation. This graph can be visualized by
1491 graphical tools such as 'hg log --graph'. In Mercurial, the DAG is
1491 graphical tools such as 'hg log --graph'. In Mercurial, the DAG is
1492 limited by the requirement for children to have at most two parents.
1492 limited by the requirement for children to have at most two parents.
1493
1493
1494
1494
1495 $ hg help hgrc.paths
1495 $ hg help hgrc.paths
1496 "paths"
1496 "paths"
1497 -------
1497 -------
1498
1498
1499 Assigns symbolic names and behavior to repositories.
1499 Assigns symbolic names and behavior to repositories.
1500
1500
1501 Options are symbolic names defining the URL or directory that is the
1501 Options are symbolic names defining the URL or directory that is the
1502 location of the repository. Example:
1502 location of the repository. Example:
1503
1503
1504 [paths]
1504 [paths]
1505 my_server = https://example.com/my_repo
1505 my_server = https://example.com/my_repo
1506 local_path = /home/me/repo
1506 local_path = /home/me/repo
1507
1507
1508 These symbolic names can be used from the command line. To pull from
1508 These symbolic names can be used from the command line. To pull from
1509 "my_server": 'hg pull my_server'. To push to "local_path": 'hg push
1509 "my_server": 'hg pull my_server'. To push to "local_path": 'hg push
1510 local_path'.
1510 local_path'.
1511
1511
1512 Options containing colons (":") denote sub-options that can influence
1512 Options containing colons (":") denote sub-options that can influence
1513 behavior for that specific path. Example:
1513 behavior for that specific path. Example:
1514
1514
1515 [paths]
1515 [paths]
1516 my_server = https://example.com/my_path
1516 my_server = https://example.com/my_path
1517 my_server:pushurl = ssh://example.com/my_path
1517 my_server:pushurl = ssh://example.com/my_path
1518
1518
1519 The following sub-options can be defined:
1519 The following sub-options can be defined:
1520
1520
1521 "pushurl"
1521 "pushurl"
1522 The URL to use for push operations. If not defined, the location
1522 The URL to use for push operations. If not defined, the location
1523 defined by the path's main entry is used.
1523 defined by the path's main entry is used.
1524
1524
1525 "pushrev"
1525 "pushrev"
1526 A revset defining which revisions to push by default.
1526 A revset defining which revisions to push by default.
1527
1527
1528 When 'hg push' is executed without a "-r" argument, the revset defined
1528 When 'hg push' is executed without a "-r" argument, the revset defined
1529 by this sub-option is evaluated to determine what to push.
1529 by this sub-option is evaluated to determine what to push.
1530
1530
1531 For example, a value of "." will push the working directory's revision
1531 For example, a value of "." will push the working directory's revision
1532 by default.
1532 by default.
1533
1533
1534 Revsets specifying bookmarks will not result in the bookmark being
1534 Revsets specifying bookmarks will not result in the bookmark being
1535 pushed.
1535 pushed.
1536
1536
1537 The following special named paths exist:
1537 The following special named paths exist:
1538
1538
1539 "default"
1539 "default"
1540 The URL or directory to use when no source or remote is specified.
1540 The URL or directory to use when no source or remote is specified.
1541
1541
1542 'hg clone' will automatically define this path to the location the
1542 'hg clone' will automatically define this path to the location the
1543 repository was cloned from.
1543 repository was cloned from.
1544
1544
1545 "default-push"
1545 "default-push"
1546 (deprecated) The URL or directory for the default 'hg push' location.
1546 (deprecated) The URL or directory for the default 'hg push' location.
1547 "default:pushurl" should be used instead.
1547 "default:pushurl" should be used instead.
1548
1548
1549 $ hg help glossary.mcguffin
1549 $ hg help glossary.mcguffin
1550 abort: help section not found
1550 abort: help section not found
1551 [255]
1551 [255]
1552
1552
1553 $ hg help glossary.mc.guffin
1553 $ hg help glossary.mc.guffin
1554 abort: help section not found
1554 abort: help section not found
1555 [255]
1555 [255]
1556
1556
1557 $ hg help template.files
1557 $ hg help template.files
1558 files List of strings. All files modified, added, or removed by
1558 files List of strings. All files modified, added, or removed by
1559 this changeset.
1559 this changeset.
1560 files(pattern)
1560 files(pattern)
1561 All files of the current changeset matching the pattern. See
1561 All files of the current changeset matching the pattern. See
1562 'hg help patterns'.
1562 'hg help patterns'.
1563
1563
1564 Test section lookup by translated message
1564 Test section lookup by translated message
1565
1565
1566 str.lower() instead of encoding.lower(str) on translated message might
1566 str.lower() instead of encoding.lower(str) on translated message might
1567 make message meaningless, because some encoding uses 0x41(A) - 0x5a(Z)
1567 make message meaningless, because some encoding uses 0x41(A) - 0x5a(Z)
1568 as the second or later byte of multi-byte character.
1568 as the second or later byte of multi-byte character.
1569
1569
1570 For example, "\x8bL\x98^" (translation of "record" in ja_JP.cp932)
1570 For example, "\x8bL\x98^" (translation of "record" in ja_JP.cp932)
1571 contains 0x4c (L). str.lower() replaces 0x4c(L) by 0x6c(l) and this
1571 contains 0x4c (L). str.lower() replaces 0x4c(L) by 0x6c(l) and this
1572 replacement makes message meaningless.
1572 replacement makes message meaningless.
1573
1573
1574 This tests that section lookup by translated string isn't broken by
1574 This tests that section lookup by translated string isn't broken by
1575 such str.lower().
1575 such str.lower().
1576
1576
1577 $ python <<EOF
1577 $ python <<EOF
1578 > def escape(s):
1578 > def escape(s):
1579 > return ''.join('\u%x' % ord(uc) for uc in s.decode('cp932'))
1579 > return ''.join('\u%x' % ord(uc) for uc in s.decode('cp932'))
1580 > # translation of "record" in ja_JP.cp932
1580 > # translation of "record" in ja_JP.cp932
1581 > upper = "\x8bL\x98^"
1581 > upper = "\x8bL\x98^"
1582 > # str.lower()-ed section name should be treated as different one
1582 > # str.lower()-ed section name should be treated as different one
1583 > lower = "\x8bl\x98^"
1583 > lower = "\x8bl\x98^"
1584 > with open('ambiguous.py', 'w') as fp:
1584 > with open('ambiguous.py', 'w') as fp:
1585 > fp.write("""# ambiguous section names in ja_JP.cp932
1585 > fp.write("""# ambiguous section names in ja_JP.cp932
1586 > u'''summary of extension
1586 > u'''summary of extension
1587 >
1587 >
1588 > %s
1588 > %s
1589 > ----
1589 > ----
1590 >
1590 >
1591 > Upper name should show only this message
1591 > Upper name should show only this message
1592 >
1592 >
1593 > %s
1593 > %s
1594 > ----
1594 > ----
1595 >
1595 >
1596 > Lower name should show only this message
1596 > Lower name should show only this message
1597 >
1597 >
1598 > subsequent section
1598 > subsequent section
1599 > ------------------
1599 > ------------------
1600 >
1600 >
1601 > This should be hidden at 'hg help ambiguous' with section name.
1601 > This should be hidden at 'hg help ambiguous' with section name.
1602 > '''
1602 > '''
1603 > """ % (escape(upper), escape(lower)))
1603 > """ % (escape(upper), escape(lower)))
1604 > EOF
1604 > EOF
1605
1605
1606 $ cat >> $HGRCPATH <<EOF
1606 $ cat >> $HGRCPATH <<EOF
1607 > [extensions]
1607 > [extensions]
1608 > ambiguous = ./ambiguous.py
1608 > ambiguous = ./ambiguous.py
1609 > EOF
1609 > EOF
1610
1610
1611 $ python <<EOF | sh
1611 $ python <<EOF | sh
1612 > upper = "\x8bL\x98^"
1612 > upper = "\x8bL\x98^"
1613 > print "hg --encoding cp932 help -e ambiguous.%s" % upper
1613 > print "hg --encoding cp932 help -e ambiguous.%s" % upper
1614 > EOF
1614 > EOF
1615 \x8bL\x98^ (esc)
1615 \x8bL\x98^ (esc)
1616 ----
1616 ----
1617
1617
1618 Upper name should show only this message
1618 Upper name should show only this message
1619
1619
1620
1620
1621 $ python <<EOF | sh
1621 $ python <<EOF | sh
1622 > lower = "\x8bl\x98^"
1622 > lower = "\x8bl\x98^"
1623 > print "hg --encoding cp932 help -e ambiguous.%s" % lower
1623 > print "hg --encoding cp932 help -e ambiguous.%s" % lower
1624 > EOF
1624 > EOF
1625 \x8bl\x98^ (esc)
1625 \x8bl\x98^ (esc)
1626 ----
1626 ----
1627
1627
1628 Lower name should show only this message
1628 Lower name should show only this message
1629
1629
1630
1630
1631 $ cat >> $HGRCPATH <<EOF
1631 $ cat >> $HGRCPATH <<EOF
1632 > [extensions]
1632 > [extensions]
1633 > ambiguous = !
1633 > ambiguous = !
1634 > EOF
1634 > EOF
1635
1635
1636 Show help content of disabled extensions
1636 Show help content of disabled extensions
1637
1637
1638 $ cat >> $HGRCPATH <<EOF
1638 $ cat >> $HGRCPATH <<EOF
1639 > [extensions]
1639 > [extensions]
1640 > ambiguous = !./ambiguous.py
1640 > ambiguous = !./ambiguous.py
1641 > EOF
1641 > EOF
1642 $ hg help -e ambiguous
1642 $ hg help -e ambiguous
1643 ambiguous extension - (no help text available)
1643 ambiguous extension - (no help text available)
1644
1644
1645 (use 'hg help extensions' for information on enabling extensions)
1645 (use 'hg help extensions' for information on enabling extensions)
1646
1646
1647 Test dynamic list of merge tools only shows up once
1647 Test dynamic list of merge tools only shows up once
1648 $ hg help merge-tools
1648 $ hg help merge-tools
1649 Merge Tools
1649 Merge Tools
1650 """""""""""
1650 """""""""""
1651
1651
1652 To merge files Mercurial uses merge tools.
1652 To merge files Mercurial uses merge tools.
1653
1653
1654 A merge tool combines two different versions of a file into a merged file.
1654 A merge tool combines two different versions of a file into a merged file.
1655 Merge tools are given the two files and the greatest common ancestor of
1655 Merge tools are given the two files and the greatest common ancestor of
1656 the two file versions, so they can determine the changes made on both
1656 the two file versions, so they can determine the changes made on both
1657 branches.
1657 branches.
1658
1658
1659 Merge tools are used both for 'hg resolve', 'hg merge', 'hg update', 'hg
1659 Merge tools are used both for 'hg resolve', 'hg merge', 'hg update', 'hg
1660 backout' and in several extensions.
1660 backout' and in several extensions.
1661
1661
1662 Usually, the merge tool tries to automatically reconcile the files by
1662 Usually, the merge tool tries to automatically reconcile the files by
1663 combining all non-overlapping changes that occurred separately in the two
1663 combining all non-overlapping changes that occurred separately in the two
1664 different evolutions of the same initial base file. Furthermore, some
1664 different evolutions of the same initial base file. Furthermore, some
1665 interactive merge programs make it easier to manually resolve conflicting
1665 interactive merge programs make it easier to manually resolve conflicting
1666 merges, either in a graphical way, or by inserting some conflict markers.
1666 merges, either in a graphical way, or by inserting some conflict markers.
1667 Mercurial does not include any interactive merge programs but relies on
1667 Mercurial does not include any interactive merge programs but relies on
1668 external tools for that.
1668 external tools for that.
1669
1669
1670 Available merge tools
1670 Available merge tools
1671 =====================
1671 =====================
1672
1672
1673 External merge tools and their properties are configured in the merge-
1673 External merge tools and their properties are configured in the merge-
1674 tools configuration section - see hgrc(5) - but they can often just be
1674 tools configuration section - see hgrc(5) - but they can often just be
1675 named by their executable.
1675 named by their executable.
1676
1676
1677 A merge tool is generally usable if its executable can be found on the
1677 A merge tool is generally usable if its executable can be found on the
1678 system and if it can handle the merge. The executable is found if it is an
1678 system and if it can handle the merge. The executable is found if it is an
1679 absolute or relative executable path or the name of an application in the
1679 absolute or relative executable path or the name of an application in the
1680 executable search path. The tool is assumed to be able to handle the merge
1680 executable search path. The tool is assumed to be able to handle the merge
1681 if it can handle symlinks if the file is a symlink, if it can handle
1681 if it can handle symlinks if the file is a symlink, if it can handle
1682 binary files if the file is binary, and if a GUI is available if the tool
1682 binary files if the file is binary, and if a GUI is available if the tool
1683 requires a GUI.
1683 requires a GUI.
1684
1684
1685 There are some internal merge tools which can be used. The internal merge
1685 There are some internal merge tools which can be used. The internal merge
1686 tools are:
1686 tools are:
1687
1687
1688 ":dump"
1688 ":dump"
1689 Creates three versions of the files to merge, containing the contents of
1689 Creates three versions of the files to merge, containing the contents of
1690 local, other and base. These files can then be used to perform a merge
1690 local, other and base. These files can then be used to perform a merge
1691 manually. If the file to be merged is named "a.txt", these files will
1691 manually. If the file to be merged is named "a.txt", these files will
1692 accordingly be named "a.txt.local", "a.txt.other" and "a.txt.base" and
1692 accordingly be named "a.txt.local", "a.txt.other" and "a.txt.base" and
1693 they will be placed in the same directory as "a.txt".
1693 they will be placed in the same directory as "a.txt".
1694
1694
1695 ":fail"
1695 ":fail"
1696 Rather than attempting to merge files that were modified on both
1696 Rather than attempting to merge files that were modified on both
1697 branches, it marks them as unresolved. The resolve command must be used
1697 branches, it marks them as unresolved. The resolve command must be used
1698 to resolve these conflicts.
1698 to resolve these conflicts.
1699
1699
1700 ":local"
1700 ":local"
1701 Uses the local 'p1()' version of files as the merged version.
1701 Uses the local 'p1()' version of files as the merged version.
1702
1702
1703 ":merge"
1703 ":merge"
1704 Uses the internal non-interactive simple merge algorithm for merging
1704 Uses the internal non-interactive simple merge algorithm for merging
1705 files. It will fail if there are any conflicts and leave markers in the
1705 files. It will fail if there are any conflicts and leave markers in the
1706 partially merged file. Markers will have two sections, one for each side
1706 partially merged file. Markers will have two sections, one for each side
1707 of merge.
1707 of merge.
1708
1708
1709 ":merge-local"
1709 ":merge-local"
1710 Like :merge, but resolve all conflicts non-interactively in favor of the
1710 Like :merge, but resolve all conflicts non-interactively in favor of the
1711 local 'p1()' changes.
1711 local 'p1()' changes.
1712
1712
1713 ":merge-other"
1713 ":merge-other"
1714 Like :merge, but resolve all conflicts non-interactively in favor of the
1714 Like :merge, but resolve all conflicts non-interactively in favor of the
1715 other 'p2()' changes.
1715 other 'p2()' changes.
1716
1716
1717 ":merge3"
1717 ":merge3"
1718 Uses the internal non-interactive simple merge algorithm for merging
1718 Uses the internal non-interactive simple merge algorithm for merging
1719 files. It will fail if there are any conflicts and leave markers in the
1719 files. It will fail if there are any conflicts and leave markers in the
1720 partially merged file. Marker will have three sections, one from each
1720 partially merged file. Marker will have three sections, one from each
1721 side of the merge and one for the base content.
1721 side of the merge and one for the base content.
1722
1722
1723 ":other"
1723 ":other"
1724 Uses the other 'p2()' version of files as the merged version.
1724 Uses the other 'p2()' version of files as the merged version.
1725
1725
1726 ":prompt"
1726 ":prompt"
1727 Asks the user which of the local 'p1()' or the other 'p2()' version to
1727 Asks the user which of the local 'p1()' or the other 'p2()' version to
1728 keep as the merged version.
1728 keep as the merged version.
1729
1729
1730 ":tagmerge"
1730 ":tagmerge"
1731 Uses the internal tag merge algorithm (experimental).
1731 Uses the internal tag merge algorithm (experimental).
1732
1732
1733 ":union"
1733 ":union"
1734 Uses the internal non-interactive simple merge algorithm for merging
1734 Uses the internal non-interactive simple merge algorithm for merging
1735 files. It will use both left and right sides for conflict regions. No
1735 files. It will use both left and right sides for conflict regions. No
1736 markers are inserted.
1736 markers are inserted.
1737
1737
1738 Internal tools are always available and do not require a GUI but will by
1738 Internal tools are always available and do not require a GUI but will by
1739 default not handle symlinks or binary files.
1739 default not handle symlinks or binary files.
1740
1740
1741 Choosing a merge tool
1741 Choosing a merge tool
1742 =====================
1742 =====================
1743
1743
1744 Mercurial uses these rules when deciding which merge tool to use:
1744 Mercurial uses these rules when deciding which merge tool to use:
1745
1745
1746 1. If a tool has been specified with the --tool option to merge or
1746 1. If a tool has been specified with the --tool option to merge or
1747 resolve, it is used. If it is the name of a tool in the merge-tools
1747 resolve, it is used. If it is the name of a tool in the merge-tools
1748 configuration, its configuration is used. Otherwise the specified tool
1748 configuration, its configuration is used. Otherwise the specified tool
1749 must be executable by the shell.
1749 must be executable by the shell.
1750 2. If the "HGMERGE" environment variable is present, its value is used and
1750 2. If the "HGMERGE" environment variable is present, its value is used and
1751 must be executable by the shell.
1751 must be executable by the shell.
1752 3. If the filename of the file to be merged matches any of the patterns in
1752 3. If the filename of the file to be merged matches any of the patterns in
1753 the merge-patterns configuration section, the first usable merge tool
1753 the merge-patterns configuration section, the first usable merge tool
1754 corresponding to a matching pattern is used. Here, binary capabilities
1754 corresponding to a matching pattern is used. Here, binary capabilities
1755 of the merge tool are not considered.
1755 of the merge tool are not considered.
1756 4. If ui.merge is set it will be considered next. If the value is not the
1756 4. If ui.merge is set it will be considered next. If the value is not the
1757 name of a configured tool, the specified value is used and must be
1757 name of a configured tool, the specified value is used and must be
1758 executable by the shell. Otherwise the named tool is used if it is
1758 executable by the shell. Otherwise the named tool is used if it is
1759 usable.
1759 usable.
1760 5. If any usable merge tools are present in the merge-tools configuration
1760 5. If any usable merge tools are present in the merge-tools configuration
1761 section, the one with the highest priority is used.
1761 section, the one with the highest priority is used.
1762 6. If a program named "hgmerge" can be found on the system, it is used -
1762 6. If a program named "hgmerge" can be found on the system, it is used -
1763 but it will by default not be used for symlinks and binary files.
1763 but it will by default not be used for symlinks and binary files.
1764 7. If the file to be merged is not binary and is not a symlink, then
1764 7. If the file to be merged is not binary and is not a symlink, then
1765 internal ":merge" is used.
1765 internal ":merge" is used.
1766 8. The merge of the file fails and must be resolved before commit.
1766 8. The merge of the file fails and must be resolved before commit.
1767
1767
1768 Note:
1768 Note:
1769 After selecting a merge program, Mercurial will by default attempt to
1769 After selecting a merge program, Mercurial will by default attempt to
1770 merge the files using a simple merge algorithm first. Only if it
1770 merge the files using a simple merge algorithm first. Only if it
1771 doesn't succeed because of conflicting changes Mercurial will actually
1771 doesn't succeed because of conflicting changes Mercurial will actually
1772 execute the merge program. Whether to use the simple merge algorithm
1772 execute the merge program. Whether to use the simple merge algorithm
1773 first can be controlled by the premerge setting of the merge tool.
1773 first can be controlled by the premerge setting of the merge tool.
1774 Premerge is enabled by default unless the file is binary or a symlink.
1774 Premerge is enabled by default unless the file is binary or a symlink.
1775
1775
1776 See the merge-tools and ui sections of hgrc(5) for details on the
1776 See the merge-tools and ui sections of hgrc(5) for details on the
1777 configuration of merge tools.
1777 configuration of merge tools.
1778
1778
1779 Test usage of section marks in help documents
1779 Test usage of section marks in help documents
1780
1780
1781 $ cd "$TESTDIR"/../doc
1781 $ cd "$TESTDIR"/../doc
1782 $ python check-seclevel.py
1782 $ python check-seclevel.py
1783 $ cd $TESTTMP
1783 $ cd $TESTTMP
1784
1784
1785 #if serve
1785 #if serve
1786
1786
1787 Test the help pages in hgweb.
1787 Test the help pages in hgweb.
1788
1788
1789 Dish up an empty repo; serve it cold.
1789 Dish up an empty repo; serve it cold.
1790
1790
1791 $ hg init "$TESTTMP/test"
1791 $ hg init "$TESTTMP/test"
1792 $ hg serve -R "$TESTTMP/test" -n test -p $HGPORT -d --pid-file=hg.pid
1792 $ hg serve -R "$TESTTMP/test" -n test -p $HGPORT -d --pid-file=hg.pid
1793 $ cat hg.pid >> $DAEMON_PIDS
1793 $ cat hg.pid >> $DAEMON_PIDS
1794
1794
1795 $ get-with-headers.py 127.0.0.1:$HGPORT "help"
1795 $ get-with-headers.py 127.0.0.1:$HGPORT "help"
1796 200 Script output follows
1796 200 Script output follows
1797
1797
1798 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
1798 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
1799 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
1799 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
1800 <head>
1800 <head>
1801 <link rel="icon" href="/static/hgicon.png" type="image/png" />
1801 <link rel="icon" href="/static/hgicon.png" type="image/png" />
1802 <meta name="robots" content="index, nofollow" />
1802 <meta name="robots" content="index, nofollow" />
1803 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
1803 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
1804 <script type="text/javascript" src="/static/mercurial.js"></script>
1804 <script type="text/javascript" src="/static/mercurial.js"></script>
1805
1805
1806 <title>Help: Index</title>
1806 <title>Help: Index</title>
1807 </head>
1807 </head>
1808 <body>
1808 <body>
1809
1809
1810 <div class="container">
1810 <div class="container">
1811 <div class="menu">
1811 <div class="menu">
1812 <div class="logo">
1812 <div class="logo">
1813 <a href="https://mercurial-scm.org/">
1813 <a href="https://mercurial-scm.org/">
1814 <img src="/static/hglogo.png" alt="mercurial" /></a>
1814 <img src="/static/hglogo.png" alt="mercurial" /></a>
1815 </div>
1815 </div>
1816 <ul>
1816 <ul>
1817 <li><a href="/shortlog">log</a></li>
1817 <li><a href="/shortlog">log</a></li>
1818 <li><a href="/graph">graph</a></li>
1818 <li><a href="/graph">graph</a></li>
1819 <li><a href="/tags">tags</a></li>
1819 <li><a href="/tags">tags</a></li>
1820 <li><a href="/bookmarks">bookmarks</a></li>
1820 <li><a href="/bookmarks">bookmarks</a></li>
1821 <li><a href="/branches">branches</a></li>
1821 <li><a href="/branches">branches</a></li>
1822 </ul>
1822 </ul>
1823 <ul>
1823 <ul>
1824 <li class="active">help</li>
1824 <li class="active">help</li>
1825 </ul>
1825 </ul>
1826 </div>
1826 </div>
1827
1827
1828 <div class="main">
1828 <div class="main">
1829 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
1829 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
1830 <form class="search" action="/log">
1830 <form class="search" action="/log">
1831
1831
1832 <p><input name="rev" id="search1" type="text" size="30" /></p>
1832 <p><input name="rev" id="search1" type="text" size="30" /></p>
1833 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
1833 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
1834 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
1834 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
1835 </form>
1835 </form>
1836 <table class="bigtable">
1836 <table class="bigtable">
1837 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
1837 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
1838
1838
1839 <tr><td>
1839 <tr><td>
1840 <a href="/help/config">
1840 <a href="/help/config">
1841 config
1841 config
1842 </a>
1842 </a>
1843 </td><td>
1843 </td><td>
1844 Configuration Files
1844 Configuration Files
1845 </td></tr>
1845 </td></tr>
1846 <tr><td>
1846 <tr><td>
1847 <a href="/help/dates">
1847 <a href="/help/dates">
1848 dates
1848 dates
1849 </a>
1849 </a>
1850 </td><td>
1850 </td><td>
1851 Date Formats
1851 Date Formats
1852 </td></tr>
1852 </td></tr>
1853 <tr><td>
1853 <tr><td>
1854 <a href="/help/diffs">
1854 <a href="/help/diffs">
1855 diffs
1855 diffs
1856 </a>
1856 </a>
1857 </td><td>
1857 </td><td>
1858 Diff Formats
1858 Diff Formats
1859 </td></tr>
1859 </td></tr>
1860 <tr><td>
1860 <tr><td>
1861 <a href="/help/environment">
1861 <a href="/help/environment">
1862 environment
1862 environment
1863 </a>
1863 </a>
1864 </td><td>
1864 </td><td>
1865 Environment Variables
1865 Environment Variables
1866 </td></tr>
1866 </td></tr>
1867 <tr><td>
1867 <tr><td>
1868 <a href="/help/extensions">
1868 <a href="/help/extensions">
1869 extensions
1869 extensions
1870 </a>
1870 </a>
1871 </td><td>
1871 </td><td>
1872 Using Additional Features
1872 Using Additional Features
1873 </td></tr>
1873 </td></tr>
1874 <tr><td>
1874 <tr><td>
1875 <a href="/help/filesets">
1875 <a href="/help/filesets">
1876 filesets
1876 filesets
1877 </a>
1877 </a>
1878 </td><td>
1878 </td><td>
1879 Specifying File Sets
1879 Specifying File Sets
1880 </td></tr>
1880 </td></tr>
1881 <tr><td>
1881 <tr><td>
1882 <a href="/help/glossary">
1882 <a href="/help/glossary">
1883 glossary
1883 glossary
1884 </a>
1884 </a>
1885 </td><td>
1885 </td><td>
1886 Glossary
1886 Glossary
1887 </td></tr>
1887 </td></tr>
1888 <tr><td>
1888 <tr><td>
1889 <a href="/help/hgignore">
1889 <a href="/help/hgignore">
1890 hgignore
1890 hgignore
1891 </a>
1891 </a>
1892 </td><td>
1892 </td><td>
1893 Syntax for Mercurial Ignore Files
1893 Syntax for Mercurial Ignore Files
1894 </td></tr>
1894 </td></tr>
1895 <tr><td>
1895 <tr><td>
1896 <a href="/help/hgweb">
1896 <a href="/help/hgweb">
1897 hgweb
1897 hgweb
1898 </a>
1898 </a>
1899 </td><td>
1899 </td><td>
1900 Configuring hgweb
1900 Configuring hgweb
1901 </td></tr>
1901 </td></tr>
1902 <tr><td>
1902 <tr><td>
1903 <a href="/help/internals">
1903 <a href="/help/internals">
1904 internals
1904 internals
1905 </a>
1905 </a>
1906 </td><td>
1906 </td><td>
1907 Technical implementation topics
1907 Technical implementation topics
1908 </td></tr>
1908 </td></tr>
1909 <tr><td>
1909 <tr><td>
1910 <a href="/help/merge-tools">
1910 <a href="/help/merge-tools">
1911 merge-tools
1911 merge-tools
1912 </a>
1912 </a>
1913 </td><td>
1913 </td><td>
1914 Merge Tools
1914 Merge Tools
1915 </td></tr>
1915 </td></tr>
1916 <tr><td>
1916 <tr><td>
1917 <a href="/help/patterns">
1917 <a href="/help/patterns">
1918 patterns
1918 patterns
1919 </a>
1919 </a>
1920 </td><td>
1920 </td><td>
1921 File Name Patterns
1921 File Name Patterns
1922 </td></tr>
1922 </td></tr>
1923 <tr><td>
1923 <tr><td>
1924 <a href="/help/phases">
1924 <a href="/help/phases">
1925 phases
1925 phases
1926 </a>
1926 </a>
1927 </td><td>
1927 </td><td>
1928 Working with Phases
1928 Working with Phases
1929 </td></tr>
1929 </td></tr>
1930 <tr><td>
1930 <tr><td>
1931 <a href="/help/revisions">
1931 <a href="/help/revisions">
1932 revisions
1932 revisions
1933 </a>
1933 </a>
1934 </td><td>
1934 </td><td>
1935 Specifying Revisions
1935 Specifying Revisions
1936 </td></tr>
1936 </td></tr>
1937 <tr><td>
1937 <tr><td>
1938 <a href="/help/scripting">
1938 <a href="/help/scripting">
1939 scripting
1939 scripting
1940 </a>
1940 </a>
1941 </td><td>
1941 </td><td>
1942 Using Mercurial from scripts and automation
1942 Using Mercurial from scripts and automation
1943 </td></tr>
1943 </td></tr>
1944 <tr><td>
1944 <tr><td>
1945 <a href="/help/subrepos">
1945 <a href="/help/subrepos">
1946 subrepos
1946 subrepos
1947 </a>
1947 </a>
1948 </td><td>
1948 </td><td>
1949 Subrepositories
1949 Subrepositories
1950 </td></tr>
1950 </td></tr>
1951 <tr><td>
1951 <tr><td>
1952 <a href="/help/templating">
1952 <a href="/help/templating">
1953 templating
1953 templating
1954 </a>
1954 </a>
1955 </td><td>
1955 </td><td>
1956 Template Usage
1956 Template Usage
1957 </td></tr>
1957 </td></tr>
1958 <tr><td>
1958 <tr><td>
1959 <a href="/help/urls">
1959 <a href="/help/urls">
1960 urls
1960 urls
1961 </a>
1961 </a>
1962 </td><td>
1962 </td><td>
1963 URL Paths
1963 URL Paths
1964 </td></tr>
1964 </td></tr>
1965 <tr><td>
1965 <tr><td>
1966 <a href="/help/topic-containing-verbose">
1966 <a href="/help/topic-containing-verbose">
1967 topic-containing-verbose
1967 topic-containing-verbose
1968 </a>
1968 </a>
1969 </td><td>
1969 </td><td>
1970 This is the topic to test omit indicating.
1970 This is the topic to test omit indicating.
1971 </td></tr>
1971 </td></tr>
1972
1972
1973
1973
1974 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
1974 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
1975
1975
1976 <tr><td>
1976 <tr><td>
1977 <a href="/help/add">
1977 <a href="/help/add">
1978 add
1978 add
1979 </a>
1979 </a>
1980 </td><td>
1980 </td><td>
1981 add the specified files on the next commit
1981 add the specified files on the next commit
1982 </td></tr>
1982 </td></tr>
1983 <tr><td>
1983 <tr><td>
1984 <a href="/help/annotate">
1984 <a href="/help/annotate">
1985 annotate
1985 annotate
1986 </a>
1986 </a>
1987 </td><td>
1987 </td><td>
1988 show changeset information by line for each file
1988 show changeset information by line for each file
1989 </td></tr>
1989 </td></tr>
1990 <tr><td>
1990 <tr><td>
1991 <a href="/help/clone">
1991 <a href="/help/clone">
1992 clone
1992 clone
1993 </a>
1993 </a>
1994 </td><td>
1994 </td><td>
1995 make a copy of an existing repository
1995 make a copy of an existing repository
1996 </td></tr>
1996 </td></tr>
1997 <tr><td>
1997 <tr><td>
1998 <a href="/help/commit">
1998 <a href="/help/commit">
1999 commit
1999 commit
2000 </a>
2000 </a>
2001 </td><td>
2001 </td><td>
2002 commit the specified files or all outstanding changes
2002 commit the specified files or all outstanding changes
2003 </td></tr>
2003 </td></tr>
2004 <tr><td>
2004 <tr><td>
2005 <a href="/help/diff">
2005 <a href="/help/diff">
2006 diff
2006 diff
2007 </a>
2007 </a>
2008 </td><td>
2008 </td><td>
2009 diff repository (or selected files)
2009 diff repository (or selected files)
2010 </td></tr>
2010 </td></tr>
2011 <tr><td>
2011 <tr><td>
2012 <a href="/help/export">
2012 <a href="/help/export">
2013 export
2013 export
2014 </a>
2014 </a>
2015 </td><td>
2015 </td><td>
2016 dump the header and diffs for one or more changesets
2016 dump the header and diffs for one or more changesets
2017 </td></tr>
2017 </td></tr>
2018 <tr><td>
2018 <tr><td>
2019 <a href="/help/forget">
2019 <a href="/help/forget">
2020 forget
2020 forget
2021 </a>
2021 </a>
2022 </td><td>
2022 </td><td>
2023 forget the specified files on the next commit
2023 forget the specified files on the next commit
2024 </td></tr>
2024 </td></tr>
2025 <tr><td>
2025 <tr><td>
2026 <a href="/help/init">
2026 <a href="/help/init">
2027 init
2027 init
2028 </a>
2028 </a>
2029 </td><td>
2029 </td><td>
2030 create a new repository in the given directory
2030 create a new repository in the given directory
2031 </td></tr>
2031 </td></tr>
2032 <tr><td>
2032 <tr><td>
2033 <a href="/help/log">
2033 <a href="/help/log">
2034 log
2034 log
2035 </a>
2035 </a>
2036 </td><td>
2036 </td><td>
2037 show revision history of entire repository or files
2037 show revision history of entire repository or files
2038 </td></tr>
2038 </td></tr>
2039 <tr><td>
2039 <tr><td>
2040 <a href="/help/merge">
2040 <a href="/help/merge">
2041 merge
2041 merge
2042 </a>
2042 </a>
2043 </td><td>
2043 </td><td>
2044 merge another revision into working directory
2044 merge another revision into working directory
2045 </td></tr>
2045 </td></tr>
2046 <tr><td>
2046 <tr><td>
2047 <a href="/help/pull">
2047 <a href="/help/pull">
2048 pull
2048 pull
2049 </a>
2049 </a>
2050 </td><td>
2050 </td><td>
2051 pull changes from the specified source
2051 pull changes from the specified source
2052 </td></tr>
2052 </td></tr>
2053 <tr><td>
2053 <tr><td>
2054 <a href="/help/push">
2054 <a href="/help/push">
2055 push
2055 push
2056 </a>
2056 </a>
2057 </td><td>
2057 </td><td>
2058 push changes to the specified destination
2058 push changes to the specified destination
2059 </td></tr>
2059 </td></tr>
2060 <tr><td>
2060 <tr><td>
2061 <a href="/help/remove">
2061 <a href="/help/remove">
2062 remove
2062 remove
2063 </a>
2063 </a>
2064 </td><td>
2064 </td><td>
2065 remove the specified files on the next commit
2065 remove the specified files on the next commit
2066 </td></tr>
2066 </td></tr>
2067 <tr><td>
2067 <tr><td>
2068 <a href="/help/serve">
2068 <a href="/help/serve">
2069 serve
2069 serve
2070 </a>
2070 </a>
2071 </td><td>
2071 </td><td>
2072 start stand-alone webserver
2072 start stand-alone webserver
2073 </td></tr>
2073 </td></tr>
2074 <tr><td>
2074 <tr><td>
2075 <a href="/help/status">
2075 <a href="/help/status">
2076 status
2076 status
2077 </a>
2077 </a>
2078 </td><td>
2078 </td><td>
2079 show changed files in the working directory
2079 show changed files in the working directory
2080 </td></tr>
2080 </td></tr>
2081 <tr><td>
2081 <tr><td>
2082 <a href="/help/summary">
2082 <a href="/help/summary">
2083 summary
2083 summary
2084 </a>
2084 </a>
2085 </td><td>
2085 </td><td>
2086 summarize working directory state
2086 summarize working directory state
2087 </td></tr>
2087 </td></tr>
2088 <tr><td>
2088 <tr><td>
2089 <a href="/help/update">
2089 <a href="/help/update">
2090 update
2090 update
2091 </a>
2091 </a>
2092 </td><td>
2092 </td><td>
2093 update working directory (or switch revisions)
2093 update working directory (or switch revisions)
2094 </td></tr>
2094 </td></tr>
2095
2095
2096
2096
2097
2097
2098 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
2098 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
2099
2099
2100 <tr><td>
2100 <tr><td>
2101 <a href="/help/addremove">
2101 <a href="/help/addremove">
2102 addremove
2102 addremove
2103 </a>
2103 </a>
2104 </td><td>
2104 </td><td>
2105 add all new files, delete all missing files
2105 add all new files, delete all missing files
2106 </td></tr>
2106 </td></tr>
2107 <tr><td>
2107 <tr><td>
2108 <a href="/help/archive">
2108 <a href="/help/archive">
2109 archive
2109 archive
2110 </a>
2110 </a>
2111 </td><td>
2111 </td><td>
2112 create an unversioned archive of a repository revision
2112 create an unversioned archive of a repository revision
2113 </td></tr>
2113 </td></tr>
2114 <tr><td>
2114 <tr><td>
2115 <a href="/help/backout">
2115 <a href="/help/backout">
2116 backout
2116 backout
2117 </a>
2117 </a>
2118 </td><td>
2118 </td><td>
2119 reverse effect of earlier changeset
2119 reverse effect of earlier changeset
2120 </td></tr>
2120 </td></tr>
2121 <tr><td>
2121 <tr><td>
2122 <a href="/help/bisect">
2122 <a href="/help/bisect">
2123 bisect
2123 bisect
2124 </a>
2124 </a>
2125 </td><td>
2125 </td><td>
2126 subdivision search of changesets
2126 subdivision search of changesets
2127 </td></tr>
2127 </td></tr>
2128 <tr><td>
2128 <tr><td>
2129 <a href="/help/bookmarks">
2129 <a href="/help/bookmarks">
2130 bookmarks
2130 bookmarks
2131 </a>
2131 </a>
2132 </td><td>
2132 </td><td>
2133 create a new bookmark or list existing bookmarks
2133 create a new bookmark or list existing bookmarks
2134 </td></tr>
2134 </td></tr>
2135 <tr><td>
2135 <tr><td>
2136 <a href="/help/branch">
2136 <a href="/help/branch">
2137 branch
2137 branch
2138 </a>
2138 </a>
2139 </td><td>
2139 </td><td>
2140 set or show the current branch name
2140 set or show the current branch name
2141 </td></tr>
2141 </td></tr>
2142 <tr><td>
2142 <tr><td>
2143 <a href="/help/branches">
2143 <a href="/help/branches">
2144 branches
2144 branches
2145 </a>
2145 </a>
2146 </td><td>
2146 </td><td>
2147 list repository named branches
2147 list repository named branches
2148 </td></tr>
2148 </td></tr>
2149 <tr><td>
2149 <tr><td>
2150 <a href="/help/bundle">
2150 <a href="/help/bundle">
2151 bundle
2151 bundle
2152 </a>
2152 </a>
2153 </td><td>
2153 </td><td>
2154 create a changegroup file
2154 create a changegroup file
2155 </td></tr>
2155 </td></tr>
2156 <tr><td>
2156 <tr><td>
2157 <a href="/help/cat">
2157 <a href="/help/cat">
2158 cat
2158 cat
2159 </a>
2159 </a>
2160 </td><td>
2160 </td><td>
2161 output the current or given revision of files
2161 output the current or given revision of files
2162 </td></tr>
2162 </td></tr>
2163 <tr><td>
2163 <tr><td>
2164 <a href="/help/config">
2164 <a href="/help/config">
2165 config
2165 config
2166 </a>
2166 </a>
2167 </td><td>
2167 </td><td>
2168 show combined config settings from all hgrc files
2168 show combined config settings from all hgrc files
2169 </td></tr>
2169 </td></tr>
2170 <tr><td>
2170 <tr><td>
2171 <a href="/help/copy">
2171 <a href="/help/copy">
2172 copy
2172 copy
2173 </a>
2173 </a>
2174 </td><td>
2174 </td><td>
2175 mark files as copied for the next commit
2175 mark files as copied for the next commit
2176 </td></tr>
2176 </td></tr>
2177 <tr><td>
2177 <tr><td>
2178 <a href="/help/files">
2178 <a href="/help/files">
2179 files
2179 files
2180 </a>
2180 </a>
2181 </td><td>
2181 </td><td>
2182 list tracked files
2182 list tracked files
2183 </td></tr>
2183 </td></tr>
2184 <tr><td>
2184 <tr><td>
2185 <a href="/help/graft">
2185 <a href="/help/graft">
2186 graft
2186 graft
2187 </a>
2187 </a>
2188 </td><td>
2188 </td><td>
2189 copy changes from other branches onto the current branch
2189 copy changes from other branches onto the current branch
2190 </td></tr>
2190 </td></tr>
2191 <tr><td>
2191 <tr><td>
2192 <a href="/help/grep">
2192 <a href="/help/grep">
2193 grep
2193 grep
2194 </a>
2194 </a>
2195 </td><td>
2195 </td><td>
2196 search revision history for a pattern in specified files
2196 search revision history for a pattern in specified files
2197 </td></tr>
2197 </td></tr>
2198 <tr><td>
2198 <tr><td>
2199 <a href="/help/heads">
2199 <a href="/help/heads">
2200 heads
2200 heads
2201 </a>
2201 </a>
2202 </td><td>
2202 </td><td>
2203 show branch heads
2203 show branch heads
2204 </td></tr>
2204 </td></tr>
2205 <tr><td>
2205 <tr><td>
2206 <a href="/help/help">
2206 <a href="/help/help">
2207 help
2207 help
2208 </a>
2208 </a>
2209 </td><td>
2209 </td><td>
2210 show help for a given topic or a help overview
2210 show help for a given topic or a help overview
2211 </td></tr>
2211 </td></tr>
2212 <tr><td>
2212 <tr><td>
2213 <a href="/help/hgalias">
2213 <a href="/help/hgalias">
2214 hgalias
2214 hgalias
2215 </a>
2215 </a>
2216 </td><td>
2216 </td><td>
2217 summarize working directory state
2217 summarize working directory state
2218 </td></tr>
2218 </td></tr>
2219 <tr><td>
2219 <tr><td>
2220 <a href="/help/identify">
2220 <a href="/help/identify">
2221 identify
2221 identify
2222 </a>
2222 </a>
2223 </td><td>
2223 </td><td>
2224 identify the working directory or specified revision
2224 identify the working directory or specified revision
2225 </td></tr>
2225 </td></tr>
2226 <tr><td>
2226 <tr><td>
2227 <a href="/help/import">
2227 <a href="/help/import">
2228 import
2228 import
2229 </a>
2229 </a>
2230 </td><td>
2230 </td><td>
2231 import an ordered set of patches
2231 import an ordered set of patches
2232 </td></tr>
2232 </td></tr>
2233 <tr><td>
2233 <tr><td>
2234 <a href="/help/incoming">
2234 <a href="/help/incoming">
2235 incoming
2235 incoming
2236 </a>
2236 </a>
2237 </td><td>
2237 </td><td>
2238 show new changesets found in source
2238 show new changesets found in source
2239 </td></tr>
2239 </td></tr>
2240 <tr><td>
2240 <tr><td>
2241 <a href="/help/manifest">
2241 <a href="/help/manifest">
2242 manifest
2242 manifest
2243 </a>
2243 </a>
2244 </td><td>
2244 </td><td>
2245 output the current or given revision of the project manifest
2245 output the current or given revision of the project manifest
2246 </td></tr>
2246 </td></tr>
2247 <tr><td>
2247 <tr><td>
2248 <a href="/help/nohelp">
2248 <a href="/help/nohelp">
2249 nohelp
2249 nohelp
2250 </a>
2250 </a>
2251 </td><td>
2251 </td><td>
2252 (no help text available)
2252 (no help text available)
2253 </td></tr>
2253 </td></tr>
2254 <tr><td>
2254 <tr><td>
2255 <a href="/help/outgoing">
2255 <a href="/help/outgoing">
2256 outgoing
2256 outgoing
2257 </a>
2257 </a>
2258 </td><td>
2258 </td><td>
2259 show changesets not found in the destination
2259 show changesets not found in the destination
2260 </td></tr>
2260 </td></tr>
2261 <tr><td>
2261 <tr><td>
2262 <a href="/help/paths">
2262 <a href="/help/paths">
2263 paths
2263 paths
2264 </a>
2264 </a>
2265 </td><td>
2265 </td><td>
2266 show aliases for remote repositories
2266 show aliases for remote repositories
2267 </td></tr>
2267 </td></tr>
2268 <tr><td>
2268 <tr><td>
2269 <a href="/help/phase">
2269 <a href="/help/phase">
2270 phase
2270 phase
2271 </a>
2271 </a>
2272 </td><td>
2272 </td><td>
2273 set or show the current phase name
2273 set or show the current phase name
2274 </td></tr>
2274 </td></tr>
2275 <tr><td>
2275 <tr><td>
2276 <a href="/help/recover">
2276 <a href="/help/recover">
2277 recover
2277 recover
2278 </a>
2278 </a>
2279 </td><td>
2279 </td><td>
2280 roll back an interrupted transaction
2280 roll back an interrupted transaction
2281 </td></tr>
2281 </td></tr>
2282 <tr><td>
2282 <tr><td>
2283 <a href="/help/rename">
2283 <a href="/help/rename">
2284 rename
2284 rename
2285 </a>
2285 </a>
2286 </td><td>
2286 </td><td>
2287 rename files; equivalent of copy + remove
2287 rename files; equivalent of copy + remove
2288 </td></tr>
2288 </td></tr>
2289 <tr><td>
2289 <tr><td>
2290 <a href="/help/resolve">
2290 <a href="/help/resolve">
2291 resolve
2291 resolve
2292 </a>
2292 </a>
2293 </td><td>
2293 </td><td>
2294 redo merges or set/view the merge status of files
2294 redo merges or set/view the merge status of files
2295 </td></tr>
2295 </td></tr>
2296 <tr><td>
2296 <tr><td>
2297 <a href="/help/revert">
2297 <a href="/help/revert">
2298 revert
2298 revert
2299 </a>
2299 </a>
2300 </td><td>
2300 </td><td>
2301 restore files to their checkout state
2301 restore files to their checkout state
2302 </td></tr>
2302 </td></tr>
2303 <tr><td>
2303 <tr><td>
2304 <a href="/help/root">
2304 <a href="/help/root">
2305 root
2305 root
2306 </a>
2306 </a>
2307 </td><td>
2307 </td><td>
2308 print the root (top) of the current working directory
2308 print the root (top) of the current working directory
2309 </td></tr>
2309 </td></tr>
2310 <tr><td>
2310 <tr><td>
2311 <a href="/help/shellalias">
2311 <a href="/help/shellalias">
2312 shellalias
2312 shellalias
2313 </a>
2313 </a>
2314 </td><td>
2314 </td><td>
2315 (no help text available)
2315 (no help text available)
2316 </td></tr>
2316 </td></tr>
2317 <tr><td>
2317 <tr><td>
2318 <a href="/help/tag">
2318 <a href="/help/tag">
2319 tag
2319 tag
2320 </a>
2320 </a>
2321 </td><td>
2321 </td><td>
2322 add one or more tags for the current or given revision
2322 add one or more tags for the current or given revision
2323 </td></tr>
2323 </td></tr>
2324 <tr><td>
2324 <tr><td>
2325 <a href="/help/tags">
2325 <a href="/help/tags">
2326 tags
2326 tags
2327 </a>
2327 </a>
2328 </td><td>
2328 </td><td>
2329 list repository tags
2329 list repository tags
2330 </td></tr>
2330 </td></tr>
2331 <tr><td>
2331 <tr><td>
2332 <a href="/help/unbundle">
2332 <a href="/help/unbundle">
2333 unbundle
2333 unbundle
2334 </a>
2334 </a>
2335 </td><td>
2335 </td><td>
2336 apply one or more changegroup files
2336 apply one or more changegroup files
2337 </td></tr>
2337 </td></tr>
2338 <tr><td>
2338 <tr><td>
2339 <a href="/help/verify">
2339 <a href="/help/verify">
2340 verify
2340 verify
2341 </a>
2341 </a>
2342 </td><td>
2342 </td><td>
2343 verify the integrity of the repository
2343 verify the integrity of the repository
2344 </td></tr>
2344 </td></tr>
2345 <tr><td>
2345 <tr><td>
2346 <a href="/help/version">
2346 <a href="/help/version">
2347 version
2347 version
2348 </a>
2348 </a>
2349 </td><td>
2349 </td><td>
2350 output version and copyright information
2350 output version and copyright information
2351 </td></tr>
2351 </td></tr>
2352
2352
2353
2353
2354 </table>
2354 </table>
2355 </div>
2355 </div>
2356 </div>
2356 </div>
2357
2357
2358
2358
2359
2359
2360 </body>
2360 </body>
2361 </html>
2361 </html>
2362
2362
2363
2363
2364 $ get-with-headers.py 127.0.0.1:$HGPORT "help/add"
2364 $ get-with-headers.py 127.0.0.1:$HGPORT "help/add"
2365 200 Script output follows
2365 200 Script output follows
2366
2366
2367 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2367 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2368 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2368 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2369 <head>
2369 <head>
2370 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2370 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2371 <meta name="robots" content="index, nofollow" />
2371 <meta name="robots" content="index, nofollow" />
2372 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2372 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2373 <script type="text/javascript" src="/static/mercurial.js"></script>
2373 <script type="text/javascript" src="/static/mercurial.js"></script>
2374
2374
2375 <title>Help: add</title>
2375 <title>Help: add</title>
2376 </head>
2376 </head>
2377 <body>
2377 <body>
2378
2378
2379 <div class="container">
2379 <div class="container">
2380 <div class="menu">
2380 <div class="menu">
2381 <div class="logo">
2381 <div class="logo">
2382 <a href="https://mercurial-scm.org/">
2382 <a href="https://mercurial-scm.org/">
2383 <img src="/static/hglogo.png" alt="mercurial" /></a>
2383 <img src="/static/hglogo.png" alt="mercurial" /></a>
2384 </div>
2384 </div>
2385 <ul>
2385 <ul>
2386 <li><a href="/shortlog">log</a></li>
2386 <li><a href="/shortlog">log</a></li>
2387 <li><a href="/graph">graph</a></li>
2387 <li><a href="/graph">graph</a></li>
2388 <li><a href="/tags">tags</a></li>
2388 <li><a href="/tags">tags</a></li>
2389 <li><a href="/bookmarks">bookmarks</a></li>
2389 <li><a href="/bookmarks">bookmarks</a></li>
2390 <li><a href="/branches">branches</a></li>
2390 <li><a href="/branches">branches</a></li>
2391 </ul>
2391 </ul>
2392 <ul>
2392 <ul>
2393 <li class="active"><a href="/help">help</a></li>
2393 <li class="active"><a href="/help">help</a></li>
2394 </ul>
2394 </ul>
2395 </div>
2395 </div>
2396
2396
2397 <div class="main">
2397 <div class="main">
2398 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2398 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2399 <h3>Help: add</h3>
2399 <h3>Help: add</h3>
2400
2400
2401 <form class="search" action="/log">
2401 <form class="search" action="/log">
2402
2402
2403 <p><input name="rev" id="search1" type="text" size="30" /></p>
2403 <p><input name="rev" id="search1" type="text" size="30" /></p>
2404 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2404 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2405 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2405 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2406 </form>
2406 </form>
2407 <div id="doc">
2407 <div id="doc">
2408 <p>
2408 <p>
2409 hg add [OPTION]... [FILE]...
2409 hg add [OPTION]... [FILE]...
2410 </p>
2410 </p>
2411 <p>
2411 <p>
2412 add the specified files on the next commit
2412 add the specified files on the next commit
2413 </p>
2413 </p>
2414 <p>
2414 <p>
2415 Schedule files to be version controlled and added to the
2415 Schedule files to be version controlled and added to the
2416 repository.
2416 repository.
2417 </p>
2417 </p>
2418 <p>
2418 <p>
2419 The files will be added to the repository at the next commit. To
2419 The files will be added to the repository at the next commit. To
2420 undo an add before that, see 'hg forget'.
2420 undo an add before that, see 'hg forget'.
2421 </p>
2421 </p>
2422 <p>
2422 <p>
2423 If no names are given, add all files to the repository (except
2423 If no names are given, add all files to the repository (except
2424 files matching &quot;.hgignore&quot;).
2424 files matching &quot;.hgignore&quot;).
2425 </p>
2425 </p>
2426 <p>
2426 <p>
2427 Examples:
2427 Examples:
2428 </p>
2428 </p>
2429 <ul>
2429 <ul>
2430 <li> New (unknown) files are added automatically by 'hg add':
2430 <li> New (unknown) files are added automatically by 'hg add':
2431 <pre>
2431 <pre>
2432 \$ ls (re)
2432 \$ ls (re)
2433 foo.c
2433 foo.c
2434 \$ hg status (re)
2434 \$ hg status (re)
2435 ? foo.c
2435 ? foo.c
2436 \$ hg add (re)
2436 \$ hg add (re)
2437 adding foo.c
2437 adding foo.c
2438 \$ hg status (re)
2438 \$ hg status (re)
2439 A foo.c
2439 A foo.c
2440 </pre>
2440 </pre>
2441 <li> Specific files to be added can be specified:
2441 <li> Specific files to be added can be specified:
2442 <pre>
2442 <pre>
2443 \$ ls (re)
2443 \$ ls (re)
2444 bar.c foo.c
2444 bar.c foo.c
2445 \$ hg status (re)
2445 \$ hg status (re)
2446 ? bar.c
2446 ? bar.c
2447 ? foo.c
2447 ? foo.c
2448 \$ hg add bar.c (re)
2448 \$ hg add bar.c (re)
2449 \$ hg status (re)
2449 \$ hg status (re)
2450 A bar.c
2450 A bar.c
2451 ? foo.c
2451 ? foo.c
2452 </pre>
2452 </pre>
2453 </ul>
2453 </ul>
2454 <p>
2454 <p>
2455 Returns 0 if all files are successfully added.
2455 Returns 0 if all files are successfully added.
2456 </p>
2456 </p>
2457 <p>
2457 <p>
2458 options ([+] can be repeated):
2458 options ([+] can be repeated):
2459 </p>
2459 </p>
2460 <table>
2460 <table>
2461 <tr><td>-I</td>
2461 <tr><td>-I</td>
2462 <td>--include PATTERN [+]</td>
2462 <td>--include PATTERN [+]</td>
2463 <td>include names matching the given patterns</td></tr>
2463 <td>include names matching the given patterns</td></tr>
2464 <tr><td>-X</td>
2464 <tr><td>-X</td>
2465 <td>--exclude PATTERN [+]</td>
2465 <td>--exclude PATTERN [+]</td>
2466 <td>exclude names matching the given patterns</td></tr>
2466 <td>exclude names matching the given patterns</td></tr>
2467 <tr><td>-S</td>
2467 <tr><td>-S</td>
2468 <td>--subrepos</td>
2468 <td>--subrepos</td>
2469 <td>recurse into subrepositories</td></tr>
2469 <td>recurse into subrepositories</td></tr>
2470 <tr><td>-n</td>
2470 <tr><td>-n</td>
2471 <td>--dry-run</td>
2471 <td>--dry-run</td>
2472 <td>do not perform actions, just print output</td></tr>
2472 <td>do not perform actions, just print output</td></tr>
2473 </table>
2473 </table>
2474 <p>
2474 <p>
2475 global options ([+] can be repeated):
2475 global options ([+] can be repeated):
2476 </p>
2476 </p>
2477 <table>
2477 <table>
2478 <tr><td>-R</td>
2478 <tr><td>-R</td>
2479 <td>--repository REPO</td>
2479 <td>--repository REPO</td>
2480 <td>repository root directory or name of overlay bundle file</td></tr>
2480 <td>repository root directory or name of overlay bundle file</td></tr>
2481 <tr><td></td>
2481 <tr><td></td>
2482 <td>--cwd DIR</td>
2482 <td>--cwd DIR</td>
2483 <td>change working directory</td></tr>
2483 <td>change working directory</td></tr>
2484 <tr><td>-y</td>
2484 <tr><td>-y</td>
2485 <td>--noninteractive</td>
2485 <td>--noninteractive</td>
2486 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
2486 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
2487 <tr><td>-q</td>
2487 <tr><td>-q</td>
2488 <td>--quiet</td>
2488 <td>--quiet</td>
2489 <td>suppress output</td></tr>
2489 <td>suppress output</td></tr>
2490 <tr><td>-v</td>
2490 <tr><td>-v</td>
2491 <td>--verbose</td>
2491 <td>--verbose</td>
2492 <td>enable additional output</td></tr>
2492 <td>enable additional output</td></tr>
2493 <tr><td></td>
2493 <tr><td></td>
2494 <td>--config CONFIG [+]</td>
2494 <td>--config CONFIG [+]</td>
2495 <td>set/override config option (use 'section.name=value')</td></tr>
2495 <td>set/override config option (use 'section.name=value')</td></tr>
2496 <tr><td></td>
2496 <tr><td></td>
2497 <td>--debug</td>
2497 <td>--debug</td>
2498 <td>enable debugging output</td></tr>
2498 <td>enable debugging output</td></tr>
2499 <tr><td></td>
2499 <tr><td></td>
2500 <td>--debugger</td>
2500 <td>--debugger</td>
2501 <td>start debugger</td></tr>
2501 <td>start debugger</td></tr>
2502 <tr><td></td>
2502 <tr><td></td>
2503 <td>--encoding ENCODE</td>
2503 <td>--encoding ENCODE</td>
2504 <td>set the charset encoding (default: ascii)</td></tr>
2504 <td>set the charset encoding (default: ascii)</td></tr>
2505 <tr><td></td>
2505 <tr><td></td>
2506 <td>--encodingmode MODE</td>
2506 <td>--encodingmode MODE</td>
2507 <td>set the charset encoding mode (default: strict)</td></tr>
2507 <td>set the charset encoding mode (default: strict)</td></tr>
2508 <tr><td></td>
2508 <tr><td></td>
2509 <td>--traceback</td>
2509 <td>--traceback</td>
2510 <td>always print a traceback on exception</td></tr>
2510 <td>always print a traceback on exception</td></tr>
2511 <tr><td></td>
2511 <tr><td></td>
2512 <td>--time</td>
2512 <td>--time</td>
2513 <td>time how long the command takes</td></tr>
2513 <td>time how long the command takes</td></tr>
2514 <tr><td></td>
2514 <tr><td></td>
2515 <td>--profile</td>
2515 <td>--profile</td>
2516 <td>print command execution profile</td></tr>
2516 <td>print command execution profile</td></tr>
2517 <tr><td></td>
2517 <tr><td></td>
2518 <td>--version</td>
2518 <td>--version</td>
2519 <td>output version information and exit</td></tr>
2519 <td>output version information and exit</td></tr>
2520 <tr><td>-h</td>
2520 <tr><td>-h</td>
2521 <td>--help</td>
2521 <td>--help</td>
2522 <td>display help and exit</td></tr>
2522 <td>display help and exit</td></tr>
2523 <tr><td></td>
2523 <tr><td></td>
2524 <td>--hidden</td>
2524 <td>--hidden</td>
2525 <td>consider hidden changesets</td></tr>
2525 <td>consider hidden changesets</td></tr>
2526 </table>
2526 </table>
2527
2527
2528 </div>
2528 </div>
2529 </div>
2529 </div>
2530 </div>
2530 </div>
2531
2531
2532
2532
2533
2533
2534 </body>
2534 </body>
2535 </html>
2535 </html>
2536
2536
2537
2537
2538 $ get-with-headers.py 127.0.0.1:$HGPORT "help/remove"
2538 $ get-with-headers.py 127.0.0.1:$HGPORT "help/remove"
2539 200 Script output follows
2539 200 Script output follows
2540
2540
2541 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2541 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2542 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2542 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2543 <head>
2543 <head>
2544 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2544 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2545 <meta name="robots" content="index, nofollow" />
2545 <meta name="robots" content="index, nofollow" />
2546 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2546 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2547 <script type="text/javascript" src="/static/mercurial.js"></script>
2547 <script type="text/javascript" src="/static/mercurial.js"></script>
2548
2548
2549 <title>Help: remove</title>
2549 <title>Help: remove</title>
2550 </head>
2550 </head>
2551 <body>
2551 <body>
2552
2552
2553 <div class="container">
2553 <div class="container">
2554 <div class="menu">
2554 <div class="menu">
2555 <div class="logo">
2555 <div class="logo">
2556 <a href="https://mercurial-scm.org/">
2556 <a href="https://mercurial-scm.org/">
2557 <img src="/static/hglogo.png" alt="mercurial" /></a>
2557 <img src="/static/hglogo.png" alt="mercurial" /></a>
2558 </div>
2558 </div>
2559 <ul>
2559 <ul>
2560 <li><a href="/shortlog">log</a></li>
2560 <li><a href="/shortlog">log</a></li>
2561 <li><a href="/graph">graph</a></li>
2561 <li><a href="/graph">graph</a></li>
2562 <li><a href="/tags">tags</a></li>
2562 <li><a href="/tags">tags</a></li>
2563 <li><a href="/bookmarks">bookmarks</a></li>
2563 <li><a href="/bookmarks">bookmarks</a></li>
2564 <li><a href="/branches">branches</a></li>
2564 <li><a href="/branches">branches</a></li>
2565 </ul>
2565 </ul>
2566 <ul>
2566 <ul>
2567 <li class="active"><a href="/help">help</a></li>
2567 <li class="active"><a href="/help">help</a></li>
2568 </ul>
2568 </ul>
2569 </div>
2569 </div>
2570
2570
2571 <div class="main">
2571 <div class="main">
2572 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2572 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2573 <h3>Help: remove</h3>
2573 <h3>Help: remove</h3>
2574
2574
2575 <form class="search" action="/log">
2575 <form class="search" action="/log">
2576
2576
2577 <p><input name="rev" id="search1" type="text" size="30" /></p>
2577 <p><input name="rev" id="search1" type="text" size="30" /></p>
2578 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2578 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2579 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2579 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2580 </form>
2580 </form>
2581 <div id="doc">
2581 <div id="doc">
2582 <p>
2582 <p>
2583 hg remove [OPTION]... FILE...
2583 hg remove [OPTION]... FILE...
2584 </p>
2584 </p>
2585 <p>
2585 <p>
2586 aliases: rm
2586 aliases: rm
2587 </p>
2587 </p>
2588 <p>
2588 <p>
2589 remove the specified files on the next commit
2589 remove the specified files on the next commit
2590 </p>
2590 </p>
2591 <p>
2591 <p>
2592 Schedule the indicated files for removal from the current branch.
2592 Schedule the indicated files for removal from the current branch.
2593 </p>
2593 </p>
2594 <p>
2594 <p>
2595 This command schedules the files to be removed at the next commit.
2595 This command schedules the files to be removed at the next commit.
2596 To undo a remove before that, see 'hg revert'. To undo added
2596 To undo a remove before that, see 'hg revert'. To undo added
2597 files, see 'hg forget'.
2597 files, see 'hg forget'.
2598 </p>
2598 </p>
2599 <p>
2599 <p>
2600 -A/--after can be used to remove only files that have already
2600 -A/--after can be used to remove only files that have already
2601 been deleted, -f/--force can be used to force deletion, and -Af
2601 been deleted, -f/--force can be used to force deletion, and -Af
2602 can be used to remove files from the next revision without
2602 can be used to remove files from the next revision without
2603 deleting them from the working directory.
2603 deleting them from the working directory.
2604 </p>
2604 </p>
2605 <p>
2605 <p>
2606 The following table details the behavior of remove for different
2606 The following table details the behavior of remove for different
2607 file states (columns) and option combinations (rows). The file
2607 file states (columns) and option combinations (rows). The file
2608 states are Added [A], Clean [C], Modified [M] and Missing [!]
2608 states are Added [A], Clean [C], Modified [M] and Missing [!]
2609 (as reported by 'hg status'). The actions are Warn, Remove
2609 (as reported by 'hg status'). The actions are Warn, Remove
2610 (from branch) and Delete (from disk):
2610 (from branch) and Delete (from disk):
2611 </p>
2611 </p>
2612 <table>
2612 <table>
2613 <tr><td>opt/state</td>
2613 <tr><td>opt/state</td>
2614 <td>A</td>
2614 <td>A</td>
2615 <td>C</td>
2615 <td>C</td>
2616 <td>M</td>
2616 <td>M</td>
2617 <td>!</td></tr>
2617 <td>!</td></tr>
2618 <tr><td>none</td>
2618 <tr><td>none</td>
2619 <td>W</td>
2619 <td>W</td>
2620 <td>RD</td>
2620 <td>RD</td>
2621 <td>W</td>
2621 <td>W</td>
2622 <td>R</td></tr>
2622 <td>R</td></tr>
2623 <tr><td>-f</td>
2623 <tr><td>-f</td>
2624 <td>R</td>
2624 <td>R</td>
2625 <td>RD</td>
2625 <td>RD</td>
2626 <td>RD</td>
2626 <td>RD</td>
2627 <td>R</td></tr>
2627 <td>R</td></tr>
2628 <tr><td>-A</td>
2628 <tr><td>-A</td>
2629 <td>W</td>
2629 <td>W</td>
2630 <td>W</td>
2630 <td>W</td>
2631 <td>W</td>
2631 <td>W</td>
2632 <td>R</td></tr>
2632 <td>R</td></tr>
2633 <tr><td>-Af</td>
2633 <tr><td>-Af</td>
2634 <td>R</td>
2634 <td>R</td>
2635 <td>R</td>
2635 <td>R</td>
2636 <td>R</td>
2636 <td>R</td>
2637 <td>R</td></tr>
2637 <td>R</td></tr>
2638 </table>
2638 </table>
2639 <p>
2639 <p>
2640 <b>Note:</b>
2640 <b>Note:</b>
2641 </p>
2641 </p>
2642 <p>
2642 <p>
2643 'hg remove' never deletes files in Added [A] state from the
2643 'hg remove' never deletes files in Added [A] state from the
2644 working directory, not even if &quot;--force&quot; is specified.
2644 working directory, not even if &quot;--force&quot; is specified.
2645 </p>
2645 </p>
2646 <p>
2646 <p>
2647 Returns 0 on success, 1 if any warnings encountered.
2647 Returns 0 on success, 1 if any warnings encountered.
2648 </p>
2648 </p>
2649 <p>
2649 <p>
2650 options ([+] can be repeated):
2650 options ([+] can be repeated):
2651 </p>
2651 </p>
2652 <table>
2652 <table>
2653 <tr><td>-A</td>
2653 <tr><td>-A</td>
2654 <td>--after</td>
2654 <td>--after</td>
2655 <td>record delete for missing files</td></tr>
2655 <td>record delete for missing files</td></tr>
2656 <tr><td>-f</td>
2656 <tr><td>-f</td>
2657 <td>--force</td>
2657 <td>--force</td>
2658 <td>forget added files, delete modified files</td></tr>
2658 <td>forget added files, delete modified files</td></tr>
2659 <tr><td>-S</td>
2659 <tr><td>-S</td>
2660 <td>--subrepos</td>
2660 <td>--subrepos</td>
2661 <td>recurse into subrepositories</td></tr>
2661 <td>recurse into subrepositories</td></tr>
2662 <tr><td>-I</td>
2662 <tr><td>-I</td>
2663 <td>--include PATTERN [+]</td>
2663 <td>--include PATTERN [+]</td>
2664 <td>include names matching the given patterns</td></tr>
2664 <td>include names matching the given patterns</td></tr>
2665 <tr><td>-X</td>
2665 <tr><td>-X</td>
2666 <td>--exclude PATTERN [+]</td>
2666 <td>--exclude PATTERN [+]</td>
2667 <td>exclude names matching the given patterns</td></tr>
2667 <td>exclude names matching the given patterns</td></tr>
2668 </table>
2668 </table>
2669 <p>
2669 <p>
2670 global options ([+] can be repeated):
2670 global options ([+] can be repeated):
2671 </p>
2671 </p>
2672 <table>
2672 <table>
2673 <tr><td>-R</td>
2673 <tr><td>-R</td>
2674 <td>--repository REPO</td>
2674 <td>--repository REPO</td>
2675 <td>repository root directory or name of overlay bundle file</td></tr>
2675 <td>repository root directory or name of overlay bundle file</td></tr>
2676 <tr><td></td>
2676 <tr><td></td>
2677 <td>--cwd DIR</td>
2677 <td>--cwd DIR</td>
2678 <td>change working directory</td></tr>
2678 <td>change working directory</td></tr>
2679 <tr><td>-y</td>
2679 <tr><td>-y</td>
2680 <td>--noninteractive</td>
2680 <td>--noninteractive</td>
2681 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
2681 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
2682 <tr><td>-q</td>
2682 <tr><td>-q</td>
2683 <td>--quiet</td>
2683 <td>--quiet</td>
2684 <td>suppress output</td></tr>
2684 <td>suppress output</td></tr>
2685 <tr><td>-v</td>
2685 <tr><td>-v</td>
2686 <td>--verbose</td>
2686 <td>--verbose</td>
2687 <td>enable additional output</td></tr>
2687 <td>enable additional output</td></tr>
2688 <tr><td></td>
2688 <tr><td></td>
2689 <td>--config CONFIG [+]</td>
2689 <td>--config CONFIG [+]</td>
2690 <td>set/override config option (use 'section.name=value')</td></tr>
2690 <td>set/override config option (use 'section.name=value')</td></tr>
2691 <tr><td></td>
2691 <tr><td></td>
2692 <td>--debug</td>
2692 <td>--debug</td>
2693 <td>enable debugging output</td></tr>
2693 <td>enable debugging output</td></tr>
2694 <tr><td></td>
2694 <tr><td></td>
2695 <td>--debugger</td>
2695 <td>--debugger</td>
2696 <td>start debugger</td></tr>
2696 <td>start debugger</td></tr>
2697 <tr><td></td>
2697 <tr><td></td>
2698 <td>--encoding ENCODE</td>
2698 <td>--encoding ENCODE</td>
2699 <td>set the charset encoding (default: ascii)</td></tr>
2699 <td>set the charset encoding (default: ascii)</td></tr>
2700 <tr><td></td>
2700 <tr><td></td>
2701 <td>--encodingmode MODE</td>
2701 <td>--encodingmode MODE</td>
2702 <td>set the charset encoding mode (default: strict)</td></tr>
2702 <td>set the charset encoding mode (default: strict)</td></tr>
2703 <tr><td></td>
2703 <tr><td></td>
2704 <td>--traceback</td>
2704 <td>--traceback</td>
2705 <td>always print a traceback on exception</td></tr>
2705 <td>always print a traceback on exception</td></tr>
2706 <tr><td></td>
2706 <tr><td></td>
2707 <td>--time</td>
2707 <td>--time</td>
2708 <td>time how long the command takes</td></tr>
2708 <td>time how long the command takes</td></tr>
2709 <tr><td></td>
2709 <tr><td></td>
2710 <td>--profile</td>
2710 <td>--profile</td>
2711 <td>print command execution profile</td></tr>
2711 <td>print command execution profile</td></tr>
2712 <tr><td></td>
2712 <tr><td></td>
2713 <td>--version</td>
2713 <td>--version</td>
2714 <td>output version information and exit</td></tr>
2714 <td>output version information and exit</td></tr>
2715 <tr><td>-h</td>
2715 <tr><td>-h</td>
2716 <td>--help</td>
2716 <td>--help</td>
2717 <td>display help and exit</td></tr>
2717 <td>display help and exit</td></tr>
2718 <tr><td></td>
2718 <tr><td></td>
2719 <td>--hidden</td>
2719 <td>--hidden</td>
2720 <td>consider hidden changesets</td></tr>
2720 <td>consider hidden changesets</td></tr>
2721 </table>
2721 </table>
2722
2722
2723 </div>
2723 </div>
2724 </div>
2724 </div>
2725 </div>
2725 </div>
2726
2726
2727
2727
2728
2728
2729 </body>
2729 </body>
2730 </html>
2730 </html>
2731
2731
2732
2732
2733 $ get-with-headers.py 127.0.0.1:$HGPORT "help/dates"
2733 $ get-with-headers.py 127.0.0.1:$HGPORT "help/dates"
2734 200 Script output follows
2734 200 Script output follows
2735
2735
2736 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2736 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2737 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2737 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2738 <head>
2738 <head>
2739 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2739 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2740 <meta name="robots" content="index, nofollow" />
2740 <meta name="robots" content="index, nofollow" />
2741 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2741 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2742 <script type="text/javascript" src="/static/mercurial.js"></script>
2742 <script type="text/javascript" src="/static/mercurial.js"></script>
2743
2743
2744 <title>Help: dates</title>
2744 <title>Help: dates</title>
2745 </head>
2745 </head>
2746 <body>
2746 <body>
2747
2747
2748 <div class="container">
2748 <div class="container">
2749 <div class="menu">
2749 <div class="menu">
2750 <div class="logo">
2750 <div class="logo">
2751 <a href="https://mercurial-scm.org/">
2751 <a href="https://mercurial-scm.org/">
2752 <img src="/static/hglogo.png" alt="mercurial" /></a>
2752 <img src="/static/hglogo.png" alt="mercurial" /></a>
2753 </div>
2753 </div>
2754 <ul>
2754 <ul>
2755 <li><a href="/shortlog">log</a></li>
2755 <li><a href="/shortlog">log</a></li>
2756 <li><a href="/graph">graph</a></li>
2756 <li><a href="/graph">graph</a></li>
2757 <li><a href="/tags">tags</a></li>
2757 <li><a href="/tags">tags</a></li>
2758 <li><a href="/bookmarks">bookmarks</a></li>
2758 <li><a href="/bookmarks">bookmarks</a></li>
2759 <li><a href="/branches">branches</a></li>
2759 <li><a href="/branches">branches</a></li>
2760 </ul>
2760 </ul>
2761 <ul>
2761 <ul>
2762 <li class="active"><a href="/help">help</a></li>
2762 <li class="active"><a href="/help">help</a></li>
2763 </ul>
2763 </ul>
2764 </div>
2764 </div>
2765
2765
2766 <div class="main">
2766 <div class="main">
2767 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2767 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2768 <h3>Help: dates</h3>
2768 <h3>Help: dates</h3>
2769
2769
2770 <form class="search" action="/log">
2770 <form class="search" action="/log">
2771
2771
2772 <p><input name="rev" id="search1" type="text" size="30" /></p>
2772 <p><input name="rev" id="search1" type="text" size="30" /></p>
2773 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2773 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2774 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2774 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2775 </form>
2775 </form>
2776 <div id="doc">
2776 <div id="doc">
2777 <h1>Date Formats</h1>
2777 <h1>Date Formats</h1>
2778 <p>
2778 <p>
2779 Some commands allow the user to specify a date, e.g.:
2779 Some commands allow the user to specify a date, e.g.:
2780 </p>
2780 </p>
2781 <ul>
2781 <ul>
2782 <li> backout, commit, import, tag: Specify the commit date.
2782 <li> backout, commit, import, tag: Specify the commit date.
2783 <li> log, revert, update: Select revision(s) by date.
2783 <li> log, revert, update: Select revision(s) by date.
2784 </ul>
2784 </ul>
2785 <p>
2785 <p>
2786 Many date formats are valid. Here are some examples:
2786 Many date formats are valid. Here are some examples:
2787 </p>
2787 </p>
2788 <ul>
2788 <ul>
2789 <li> &quot;Wed Dec 6 13:18:29 2006&quot; (local timezone assumed)
2789 <li> &quot;Wed Dec 6 13:18:29 2006&quot; (local timezone assumed)
2790 <li> &quot;Dec 6 13:18 -0600&quot; (year assumed, time offset provided)
2790 <li> &quot;Dec 6 13:18 -0600&quot; (year assumed, time offset provided)
2791 <li> &quot;Dec 6 13:18 UTC&quot; (UTC and GMT are aliases for +0000)
2791 <li> &quot;Dec 6 13:18 UTC&quot; (UTC and GMT are aliases for +0000)
2792 <li> &quot;Dec 6&quot; (midnight)
2792 <li> &quot;Dec 6&quot; (midnight)
2793 <li> &quot;13:18&quot; (today assumed)
2793 <li> &quot;13:18&quot; (today assumed)
2794 <li> &quot;3:39&quot; (3:39AM assumed)
2794 <li> &quot;3:39&quot; (3:39AM assumed)
2795 <li> &quot;3:39pm&quot; (15:39)
2795 <li> &quot;3:39pm&quot; (15:39)
2796 <li> &quot;2006-12-06 13:18:29&quot; (ISO 8601 format)
2796 <li> &quot;2006-12-06 13:18:29&quot; (ISO 8601 format)
2797 <li> &quot;2006-12-6 13:18&quot;
2797 <li> &quot;2006-12-6 13:18&quot;
2798 <li> &quot;2006-12-6&quot;
2798 <li> &quot;2006-12-6&quot;
2799 <li> &quot;12-6&quot;
2799 <li> &quot;12-6&quot;
2800 <li> &quot;12/6&quot;
2800 <li> &quot;12/6&quot;
2801 <li> &quot;12/6/6&quot; (Dec 6 2006)
2801 <li> &quot;12/6/6&quot; (Dec 6 2006)
2802 <li> &quot;today&quot; (midnight)
2802 <li> &quot;today&quot; (midnight)
2803 <li> &quot;yesterday&quot; (midnight)
2803 <li> &quot;yesterday&quot; (midnight)
2804 <li> &quot;now&quot; - right now
2804 <li> &quot;now&quot; - right now
2805 </ul>
2805 </ul>
2806 <p>
2806 <p>
2807 Lastly, there is Mercurial's internal format:
2807 Lastly, there is Mercurial's internal format:
2808 </p>
2808 </p>
2809 <ul>
2809 <ul>
2810 <li> &quot;1165411109 0&quot; (Wed Dec 6 13:18:29 2006 UTC)
2810 <li> &quot;1165411109 0&quot; (Wed Dec 6 13:18:29 2006 UTC)
2811 </ul>
2811 </ul>
2812 <p>
2812 <p>
2813 This is the internal representation format for dates. The first number
2813 This is the internal representation format for dates. The first number
2814 is the number of seconds since the epoch (1970-01-01 00:00 UTC). The
2814 is the number of seconds since the epoch (1970-01-01 00:00 UTC). The
2815 second is the offset of the local timezone, in seconds west of UTC
2815 second is the offset of the local timezone, in seconds west of UTC
2816 (negative if the timezone is east of UTC).
2816 (negative if the timezone is east of UTC).
2817 </p>
2817 </p>
2818 <p>
2818 <p>
2819 The log command also accepts date ranges:
2819 The log command also accepts date ranges:
2820 </p>
2820 </p>
2821 <ul>
2821 <ul>
2822 <li> &quot;&lt;DATE&quot; - at or before a given date/time
2822 <li> &quot;&lt;DATE&quot; - at or before a given date/time
2823 <li> &quot;&gt;DATE&quot; - on or after a given date/time
2823 <li> &quot;&gt;DATE&quot; - on or after a given date/time
2824 <li> &quot;DATE to DATE&quot; - a date range, inclusive
2824 <li> &quot;DATE to DATE&quot; - a date range, inclusive
2825 <li> &quot;-DAYS&quot; - within a given number of days of today
2825 <li> &quot;-DAYS&quot; - within a given number of days of today
2826 </ul>
2826 </ul>
2827
2827
2828 </div>
2828 </div>
2829 </div>
2829 </div>
2830 </div>
2830 </div>
2831
2831
2832
2832
2833
2833
2834 </body>
2834 </body>
2835 </html>
2835 </html>
2836
2836
2837
2837
2838 Sub-topic indexes rendered properly
2838 Sub-topic indexes rendered properly
2839
2839
2840 $ get-with-headers.py 127.0.0.1:$HGPORT "help/internals"
2840 $ get-with-headers.py 127.0.0.1:$HGPORT "help/internals"
2841 200 Script output follows
2841 200 Script output follows
2842
2842
2843 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2843 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2844 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2844 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2845 <head>
2845 <head>
2846 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2846 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2847 <meta name="robots" content="index, nofollow" />
2847 <meta name="robots" content="index, nofollow" />
2848 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2848 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2849 <script type="text/javascript" src="/static/mercurial.js"></script>
2849 <script type="text/javascript" src="/static/mercurial.js"></script>
2850
2850
2851 <title>Help: internals</title>
2851 <title>Help: internals</title>
2852 </head>
2852 </head>
2853 <body>
2853 <body>
2854
2854
2855 <div class="container">
2855 <div class="container">
2856 <div class="menu">
2856 <div class="menu">
2857 <div class="logo">
2857 <div class="logo">
2858 <a href="https://mercurial-scm.org/">
2858 <a href="https://mercurial-scm.org/">
2859 <img src="/static/hglogo.png" alt="mercurial" /></a>
2859 <img src="/static/hglogo.png" alt="mercurial" /></a>
2860 </div>
2860 </div>
2861 <ul>
2861 <ul>
2862 <li><a href="/shortlog">log</a></li>
2862 <li><a href="/shortlog">log</a></li>
2863 <li><a href="/graph">graph</a></li>
2863 <li><a href="/graph">graph</a></li>
2864 <li><a href="/tags">tags</a></li>
2864 <li><a href="/tags">tags</a></li>
2865 <li><a href="/bookmarks">bookmarks</a></li>
2865 <li><a href="/bookmarks">bookmarks</a></li>
2866 <li><a href="/branches">branches</a></li>
2866 <li><a href="/branches">branches</a></li>
2867 </ul>
2867 </ul>
2868 <ul>
2868 <ul>
2869 <li><a href="/help">help</a></li>
2869 <li><a href="/help">help</a></li>
2870 </ul>
2870 </ul>
2871 </div>
2871 </div>
2872
2872
2873 <div class="main">
2873 <div class="main">
2874 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2874 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2875 <form class="search" action="/log">
2875 <form class="search" action="/log">
2876
2876
2877 <p><input name="rev" id="search1" type="text" size="30" /></p>
2877 <p><input name="rev" id="search1" type="text" size="30" /></p>
2878 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2878 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2879 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2879 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2880 </form>
2880 </form>
2881 <table class="bigtable">
2881 <table class="bigtable">
2882 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
2882 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
2883
2883
2884 <tr><td>
2884 <tr><td>
2885 <a href="/help/internals.bundles">
2885 <a href="/help/internals.bundles">
2886 bundles
2886 bundles
2887 </a>
2887 </a>
2888 </td><td>
2888 </td><td>
2889 Bundles
2889 Bundles
2890 </td></tr>
2890 </td></tr>
2891 <tr><td>
2891 <tr><td>
2892 <a href="/help/internals.changegroups">
2892 <a href="/help/internals.changegroups">
2893 changegroups
2893 changegroups
2894 </a>
2894 </a>
2895 </td><td>
2895 </td><td>
2896 Changegroups
2896 Changegroups
2897 </td></tr>
2897 </td></tr>
2898 <tr><td>
2898 <tr><td>
2899 <a href="/help/internals.requirements">
2899 <a href="/help/internals.requirements">
2900 requirements
2900 requirements
2901 </a>
2901 </a>
2902 </td><td>
2902 </td><td>
2903 Repository Requirements
2903 Repository Requirements
2904 </td></tr>
2904 </td></tr>
2905 <tr><td>
2905 <tr><td>
2906 <a href="/help/internals.revlogs">
2906 <a href="/help/internals.revlogs">
2907 revlogs
2907 revlogs
2908 </a>
2908 </a>
2909 </td><td>
2909 </td><td>
2910 Revision Logs
2910 Revision Logs
2911 </td></tr>
2911 </td></tr>
2912 <tr><td>
2912 <tr><td>
2913 <a href="/help/internals.wireprotocol">
2913 <a href="/help/internals.wireprotocol">
2914 wireprotocol
2914 wireprotocol
2915 </a>
2915 </a>
2916 </td><td>
2916 </td><td>
2917 Wire Protocol
2917 Wire Protocol
2918 </td></tr>
2918 </td></tr>
2919
2919
2920
2920
2921
2921
2922
2922
2923
2923
2924 </table>
2924 </table>
2925 </div>
2925 </div>
2926 </div>
2926 </div>
2927
2927
2928
2928
2929
2929
2930 </body>
2930 </body>
2931 </html>
2931 </html>
2932
2932
2933
2933
2934 Sub-topic topics rendered properly
2934 Sub-topic topics rendered properly
2935
2935
2936 $ get-with-headers.py 127.0.0.1:$HGPORT "help/internals.changegroups"
2936 $ get-with-headers.py 127.0.0.1:$HGPORT "help/internals.changegroups"
2937 200 Script output follows
2937 200 Script output follows
2938
2938
2939 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2939 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2940 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2940 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2941 <head>
2941 <head>
2942 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2942 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2943 <meta name="robots" content="index, nofollow" />
2943 <meta name="robots" content="index, nofollow" />
2944 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2944 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2945 <script type="text/javascript" src="/static/mercurial.js"></script>
2945 <script type="text/javascript" src="/static/mercurial.js"></script>
2946
2946
2947 <title>Help: internals.changegroups</title>
2947 <title>Help: internals.changegroups</title>
2948 </head>
2948 </head>
2949 <body>
2949 <body>
2950
2950
2951 <div class="container">
2951 <div class="container">
2952 <div class="menu">
2952 <div class="menu">
2953 <div class="logo">
2953 <div class="logo">
2954 <a href="https://mercurial-scm.org/">
2954 <a href="https://mercurial-scm.org/">
2955 <img src="/static/hglogo.png" alt="mercurial" /></a>
2955 <img src="/static/hglogo.png" alt="mercurial" /></a>
2956 </div>
2956 </div>
2957 <ul>
2957 <ul>
2958 <li><a href="/shortlog">log</a></li>
2958 <li><a href="/shortlog">log</a></li>
2959 <li><a href="/graph">graph</a></li>
2959 <li><a href="/graph">graph</a></li>
2960 <li><a href="/tags">tags</a></li>
2960 <li><a href="/tags">tags</a></li>
2961 <li><a href="/bookmarks">bookmarks</a></li>
2961 <li><a href="/bookmarks">bookmarks</a></li>
2962 <li><a href="/branches">branches</a></li>
2962 <li><a href="/branches">branches</a></li>
2963 </ul>
2963 </ul>
2964 <ul>
2964 <ul>
2965 <li class="active"><a href="/help">help</a></li>
2965 <li class="active"><a href="/help">help</a></li>
2966 </ul>
2966 </ul>
2967 </div>
2967 </div>
2968
2968
2969 <div class="main">
2969 <div class="main">
2970 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2970 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2971 <h3>Help: internals.changegroups</h3>
2971 <h3>Help: internals.changegroups</h3>
2972
2972
2973 <form class="search" action="/log">
2973 <form class="search" action="/log">
2974
2974
2975 <p><input name="rev" id="search1" type="text" size="30" /></p>
2975 <p><input name="rev" id="search1" type="text" size="30" /></p>
2976 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2976 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2977 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2977 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2978 </form>
2978 </form>
2979 <div id="doc">
2979 <div id="doc">
2980 <h1>Changegroups</h1>
2980 <h1>Changegroups</h1>
2981 <p>
2981 <p>
2982 Changegroups are representations of repository revlog data, specifically
2982 Changegroups are representations of repository revlog data, specifically
2983 the changelog, manifest, and filelogs.
2983 the changelog, manifest, and filelogs.
2984 </p>
2984 </p>
2985 <p>
2985 <p>
2986 There are 3 versions of changegroups: &quot;1&quot;, &quot;2&quot;, and &quot;3&quot;. From a
2986 There are 3 versions of changegroups: &quot;1&quot;, &quot;2&quot;, and &quot;3&quot;. From a
2987 high-level, versions &quot;1&quot; and &quot;2&quot; are almost exactly the same, with
2987 high-level, versions &quot;1&quot; and &quot;2&quot; are almost exactly the same, with
2988 the only difference being a header on entries in the changeset
2988 the only difference being a header on entries in the changeset
2989 segment. Version &quot;3&quot; adds support for exchanging treemanifests and
2989 segment. Version &quot;3&quot; adds support for exchanging treemanifests and
2990 includes revlog flags in the delta header.
2990 includes revlog flags in the delta header.
2991 </p>
2991 </p>
2992 <p>
2992 <p>
2993 Changegroups consists of 3 logical segments:
2993 Changegroups consists of 3 logical segments:
2994 </p>
2994 </p>
2995 <pre>
2995 <pre>
2996 +---------------------------------+
2996 +---------------------------------+
2997 | | | |
2997 | | | |
2998 | changeset | manifest | filelogs |
2998 | changeset | manifest | filelogs |
2999 | | | |
2999 | | | |
3000 +---------------------------------+
3000 +---------------------------------+
3001 </pre>
3001 </pre>
3002 <p>
3002 <p>
3003 The principle building block of each segment is a *chunk*. A *chunk*
3003 The principle building block of each segment is a *chunk*. A *chunk*
3004 is a framed piece of data:
3004 is a framed piece of data:
3005 </p>
3005 </p>
3006 <pre>
3006 <pre>
3007 +---------------------------------------+
3007 +---------------------------------------+
3008 | | |
3008 | | |
3009 | length | data |
3009 | length | data |
3010 | (32 bits) | &lt;length&gt; bytes |
3010 | (32 bits) | &lt;length&gt; bytes |
3011 | | |
3011 | | |
3012 +---------------------------------------+
3012 +---------------------------------------+
3013 </pre>
3013 </pre>
3014 <p>
3014 <p>
3015 Each chunk starts with a 32-bit big-endian signed integer indicating
3015 Each chunk starts with a 32-bit big-endian signed integer indicating
3016 the length of the raw data that follows.
3016 the length of the raw data that follows.
3017 </p>
3017 </p>
3018 <p>
3018 <p>
3019 There is a special case chunk that has 0 length (&quot;0x00000000&quot;). We
3019 There is a special case chunk that has 0 length (&quot;0x00000000&quot;). We
3020 call this an *empty chunk*.
3020 call this an *empty chunk*.
3021 </p>
3021 </p>
3022 <h2>Delta Groups</h2>
3022 <h2>Delta Groups</h2>
3023 <p>
3023 <p>
3024 A *delta group* expresses the content of a revlog as a series of deltas,
3024 A *delta group* expresses the content of a revlog as a series of deltas,
3025 or patches against previous revisions.
3025 or patches against previous revisions.
3026 </p>
3026 </p>
3027 <p>
3027 <p>
3028 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
3028 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
3029 to signal the end of the delta group:
3029 to signal the end of the delta group:
3030 </p>
3030 </p>
3031 <pre>
3031 <pre>
3032 +------------------------------------------------------------------------+
3032 +------------------------------------------------------------------------+
3033 | | | | | |
3033 | | | | | |
3034 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
3034 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
3035 | (32 bits) | (various) | (32 bits) | (various) | (32 bits) |
3035 | (32 bits) | (various) | (32 bits) | (various) | (32 bits) |
3036 | | | | | |
3036 | | | | | |
3037 +------------------------------------------------------------+-----------+
3037 +------------------------------------------------------------+-----------+
3038 </pre>
3038 </pre>
3039 <p>
3039 <p>
3040 Each *chunk*'s data consists of the following:
3040 Each *chunk*'s data consists of the following:
3041 </p>
3041 </p>
3042 <pre>
3042 <pre>
3043 +-----------------------------------------+
3043 +-----------------------------------------+
3044 | | | |
3044 | | | |
3045 | delta header | mdiff header | delta |
3045 | delta header | mdiff header | delta |
3046 | (various) | (12 bytes) | (various) |
3046 | (various) | (12 bytes) | (various) |
3047 | | | |
3047 | | | |
3048 +-----------------------------------------+
3048 +-----------------------------------------+
3049 </pre>
3049 </pre>
3050 <p>
3050 <p>
3051 The *length* field is the byte length of the remaining 3 logical pieces
3051 The *length* field is the byte length of the remaining 3 logical pieces
3052 of data. The *delta* is a diff from an existing entry in the changelog.
3052 of data. The *delta* is a diff from an existing entry in the changelog.
3053 </p>
3053 </p>
3054 <p>
3054 <p>
3055 The *delta header* is different between versions &quot;1&quot;, &quot;2&quot;, and
3055 The *delta header* is different between versions &quot;1&quot;, &quot;2&quot;, and
3056 &quot;3&quot; of the changegroup format.
3056 &quot;3&quot; of the changegroup format.
3057 </p>
3057 </p>
3058 <p>
3058 <p>
3059 Version 1:
3059 Version 1:
3060 </p>
3060 </p>
3061 <pre>
3061 <pre>
3062 +------------------------------------------------------+
3062 +------------------------------------------------------+
3063 | | | | |
3063 | | | | |
3064 | node | p1 node | p2 node | link node |
3064 | node | p1 node | p2 node | link node |
3065 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3065 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3066 | | | | |
3066 | | | | |
3067 +------------------------------------------------------+
3067 +------------------------------------------------------+
3068 </pre>
3068 </pre>
3069 <p>
3069 <p>
3070 Version 2:
3070 Version 2:
3071 </p>
3071 </p>
3072 <pre>
3072 <pre>
3073 +------------------------------------------------------------------+
3073 +------------------------------------------------------------------+
3074 | | | | | |
3074 | | | | | |
3075 | node | p1 node | p2 node | base node | link node |
3075 | node | p1 node | p2 node | base node | link node |
3076 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3076 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3077 | | | | | |
3077 | | | | | |
3078 +------------------------------------------------------------------+
3078 +------------------------------------------------------------------+
3079 </pre>
3079 </pre>
3080 <p>
3080 <p>
3081 Version 3:
3081 Version 3:
3082 </p>
3082 </p>
3083 <pre>
3083 <pre>
3084 +------------------------------------------------------------------------------+
3084 +------------------------------------------------------------------------------+
3085 | | | | | | |
3085 | | | | | | |
3086 | node | p1 node | p2 node | base node | link node | flags |
3086 | node | p1 node | p2 node | base node | link node | flags |
3087 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
3087 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
3088 | | | | | | |
3088 | | | | | | |
3089 +------------------------------------------------------------------------------+
3089 +------------------------------------------------------------------------------+
3090 </pre>
3090 </pre>
3091 <p>
3091 <p>
3092 The *mdiff header* consists of 3 32-bit big-endian signed integers
3092 The *mdiff header* consists of 3 32-bit big-endian signed integers
3093 describing offsets at which to apply the following delta content:
3093 describing offsets at which to apply the following delta content:
3094 </p>
3094 </p>
3095 <pre>
3095 <pre>
3096 +-------------------------------------+
3096 +-------------------------------------+
3097 | | | |
3097 | | | |
3098 | offset | old length | new length |
3098 | offset | old length | new length |
3099 | (32 bits) | (32 bits) | (32 bits) |
3099 | (32 bits) | (32 bits) | (32 bits) |
3100 | | | |
3100 | | | |
3101 +-------------------------------------+
3101 +-------------------------------------+
3102 </pre>
3102 </pre>
3103 <p>
3103 <p>
3104 In version 1, the delta is always applied against the previous node from
3104 In version 1, the delta is always applied against the previous node from
3105 the changegroup or the first parent if this is the first entry in the
3105 the changegroup or the first parent if this is the first entry in the
3106 changegroup.
3106 changegroup.
3107 </p>
3107 </p>
3108 <p>
3108 <p>
3109 In version 2, the delta base node is encoded in the entry in the
3109 In version 2, the delta base node is encoded in the entry in the
3110 changegroup. This allows the delta to be expressed against any parent,
3110 changegroup. This allows the delta to be expressed against any parent,
3111 which can result in smaller deltas and more efficient encoding of data.
3111 which can result in smaller deltas and more efficient encoding of data.
3112 </p>
3112 </p>
3113 <h2>Changeset Segment</h2>
3113 <h2>Changeset Segment</h2>
3114 <p>
3114 <p>
3115 The *changeset segment* consists of a single *delta group* holding
3115 The *changeset segment* consists of a single *delta group* holding
3116 changelog data. It is followed by an *empty chunk* to denote the
3116 changelog data. It is followed by an *empty chunk* to denote the
3117 boundary to the *manifests segment*.
3117 boundary to the *manifests segment*.
3118 </p>
3118 </p>
3119 <h2>Manifest Segment</h2>
3119 <h2>Manifest Segment</h2>
3120 <p>
3120 <p>
3121 The *manifest segment* consists of a single *delta group* holding
3121 The *manifest segment* consists of a single *delta group* holding
3122 manifest data. It is followed by an *empty chunk* to denote the boundary
3122 manifest data. It is followed by an *empty chunk* to denote the boundary
3123 to the *filelogs segment*.
3123 to the *filelogs segment*.
3124 </p>
3124 </p>
3125 <h2>Filelogs Segment</h2>
3125 <h2>Filelogs Segment</h2>
3126 <p>
3126 <p>
3127 The *filelogs* segment consists of multiple sub-segments, each
3127 The *filelogs* segment consists of multiple sub-segments, each
3128 corresponding to an individual file whose data is being described:
3128 corresponding to an individual file whose data is being described:
3129 </p>
3129 </p>
3130 <pre>
3130 <pre>
3131 +--------------------------------------+
3131 +--------------------------------------+
3132 | | | | |
3132 | | | | |
3133 | filelog0 | filelog1 | filelog2 | ... |
3133 | filelog0 | filelog1 | filelog2 | ... |
3134 | | | | |
3134 | | | | |
3135 +--------------------------------------+
3135 +--------------------------------------+
3136 </pre>
3136 </pre>
3137 <p>
3137 <p>
3138 In version &quot;3&quot; of the changegroup format, filelogs may include
3138 In version &quot;3&quot; of the changegroup format, filelogs may include
3139 directory logs when treemanifests are in use. directory logs are
3139 directory logs when treemanifests are in use. directory logs are
3140 identified by having a trailing '/' on their filename (see below).
3140 identified by having a trailing '/' on their filename (see below).
3141 </p>
3141 </p>
3142 <p>
3142 <p>
3143 The final filelog sub-segment is followed by an *empty chunk* to denote
3143 The final filelog sub-segment is followed by an *empty chunk* to denote
3144 the end of the segment and the overall changegroup.
3144 the end of the segment and the overall changegroup.
3145 </p>
3145 </p>
3146 <p>
3146 <p>
3147 Each filelog sub-segment consists of the following:
3147 Each filelog sub-segment consists of the following:
3148 </p>
3148 </p>
3149 <pre>
3149 <pre>
3150 +------------------------------------------+
3150 +------------------------------------------+
3151 | | | |
3151 | | | |
3152 | filename size | filename | delta group |
3152 | filename size | filename | delta group |
3153 | (32 bits) | (various) | (various) |
3153 | (32 bits) | (various) | (various) |
3154 | | | |
3154 | | | |
3155 +------------------------------------------+
3155 +------------------------------------------+
3156 </pre>
3156 </pre>
3157 <p>
3157 <p>
3158 That is, a *chunk* consisting of the filename (not terminated or padded)
3158 That is, a *chunk* consisting of the filename (not terminated or padded)
3159 followed by N chunks constituting the *delta group* for this file.
3159 followed by N chunks constituting the *delta group* for this file.
3160 </p>
3160 </p>
3161
3161
3162 </div>
3162 </div>
3163 </div>
3163 </div>
3164 </div>
3164 </div>
3165
3165
3166
3166
3167
3167
3168 </body>
3168 </body>
3169 </html>
3169 </html>
3170
3170
3171
3171
3172 $ killdaemons.py
3172 $ killdaemons.py
3173
3173
3174 #endif
3174 #endif
@@ -1,231 +1,231 b''
1 hide outer repo
1 hide outer repo
2 $ hg init
2 $ hg init
3
3
4 Use hgrc within $TESTTMP
4 Use hgrc within $TESTTMP
5
5
6 $ HGRCPATH=`pwd`/hgrc
6 $ HGRCPATH=`pwd`/hgrc
7 $ export HGRCPATH
7 $ export HGRCPATH
8
8
9 Use an alternate var for scribbling on hgrc to keep check-code from
9 Use an alternate var for scribbling on hgrc to keep check-code from
10 complaining about the important settings we may be overwriting:
10 complaining about the important settings we may be overwriting:
11
11
12 $ HGRC=`pwd`/hgrc
12 $ HGRC=`pwd`/hgrc
13 $ export HGRC
13 $ export HGRC
14
14
15 Basic syntax error
15 Basic syntax error
16
16
17 $ echo "invalid" > $HGRC
17 $ echo "invalid" > $HGRC
18 $ hg version
18 $ hg version
19 hg: parse error at $TESTTMP/hgrc:1: invalid
19 hg: parse error at $TESTTMP/hgrc:1: invalid
20 [255]
20 [255]
21 $ echo "" > $HGRC
21 $ echo "" > $HGRC
22
22
23 Issue1199: Can't use '%' in hgrc (eg url encoded username)
23 Issue1199: Can't use '%' in hgrc (eg url encoded username)
24
24
25 $ hg init "foo%bar"
25 $ hg init "foo%bar"
26 $ hg clone "foo%bar" foobar
26 $ hg clone "foo%bar" foobar
27 updating to branch default
27 updating to branch default
28 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
28 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
29 $ cd foobar
29 $ cd foobar
30 $ cat .hg/hgrc
30 $ cat .hg/hgrc
31 # example repository config (see 'hg help config' for more info)
31 # example repository config (see 'hg help config' for more info)
32 [paths]
32 [paths]
33 default = $TESTTMP/foo%bar (glob)
33 default = $TESTTMP/foo%bar (glob)
34
34
35 # path aliases to other clones of this repo in URLs or filesystem paths
35 # path aliases to other clones of this repo in URLs or filesystem paths
36 # (see 'hg help config.paths' for more info)
36 # (see 'hg help config.paths' for more info)
37 #
37 #
38 # default-push = ssh://jdoe@example.net/hg/jdoes-fork
38 # default-push = ssh://jdoe@example.net/hg/jdoes-fork
39 # my-fork = ssh://jdoe@example.net/hg/jdoes-fork
39 # my-fork = ssh://jdoe@example.net/hg/jdoes-fork
40 # my-clone = /home/jdoe/jdoes-clone
40 # my-clone = /home/jdoe/jdoes-clone
41
41
42 [ui]
42 [ui]
43 # name and email (local to this repository, optional), e.g.
43 # name and email (local to this repository, optional), e.g.
44 # username = Jane Doe <jdoe@example.com>
44 # username = Jane Doe <jdoe@example.com>
45 $ hg paths
45 $ hg paths
46 default = $TESTTMP/foo%bar (glob)
46 default = $TESTTMP/foo%bar (glob)
47 $ hg showconfig
47 $ hg showconfig
48 bundle.mainreporoot=$TESTTMP/foobar (glob)
48 bundle.mainreporoot=$TESTTMP/foobar (glob)
49 paths.default=$TESTTMP/foo%bar (glob)
49 paths.default=$TESTTMP/foo%bar (glob)
50 $ cd ..
50 $ cd ..
51
51
52 issue1829: wrong indentation
52 issue1829: wrong indentation
53
53
54 $ echo '[foo]' > $HGRC
54 $ echo '[foo]' > $HGRC
55 $ echo ' x = y' >> $HGRC
55 $ echo ' x = y' >> $HGRC
56 $ hg version
56 $ hg version
57 hg: parse error at $TESTTMP/hgrc:2: x = y
57 hg: parse error at $TESTTMP/hgrc:2: x = y
58 unexpected leading whitespace
58 unexpected leading whitespace
59 [255]
59 [255]
60
60
61 $ $PYTHON -c "print '[foo]\nbar = a\n b\n c \n de\n fg \nbaz = bif cb \n'" \
61 $ $PYTHON -c "print '[foo]\nbar = a\n b\n c \n de\n fg \nbaz = bif cb \n'" \
62 > > $HGRC
62 > > $HGRC
63 $ hg showconfig foo
63 $ hg showconfig foo
64 foo.bar=a\nb\nc\nde\nfg
64 foo.bar=a\nb\nc\nde\nfg
65 foo.baz=bif cb
65 foo.baz=bif cb
66
66
67 $ FAKEPATH=/path/to/nowhere
67 $ FAKEPATH=/path/to/nowhere
68 $ export FAKEPATH
68 $ export FAKEPATH
69 $ echo '%include $FAKEPATH/no-such-file' > $HGRC
69 $ echo '%include $FAKEPATH/no-such-file' > $HGRC
70 $ hg version
70 $ hg version
71 Mercurial Distributed SCM (version *) (glob)
71 Mercurial Distributed SCM (version *) (glob)
72 (see https://mercurial-scm.org for more information)
72 (see https://mercurial-scm.org for more information)
73
73
74 Copyright (C) 2005-2016 Matt Mackall and others
74 Copyright (C) 2005-* Matt Mackall and others (glob)
75 This is free software; see the source for copying conditions. There is NO
75 This is free software; see the source for copying conditions. There is NO
76 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
76 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
77 $ unset FAKEPATH
77 $ unset FAKEPATH
78
78
79 make sure global options given on the cmdline take precedence
79 make sure global options given on the cmdline take precedence
80
80
81 $ hg showconfig --config ui.verbose=True --quiet
81 $ hg showconfig --config ui.verbose=True --quiet
82 bundle.mainreporoot=$TESTTMP
82 bundle.mainreporoot=$TESTTMP
83 ui.verbose=False
83 ui.verbose=False
84 ui.debug=False
84 ui.debug=False
85 ui.quiet=True
85 ui.quiet=True
86
86
87 $ touch foobar/untracked
87 $ touch foobar/untracked
88 $ cat >> foobar/.hg/hgrc <<EOF
88 $ cat >> foobar/.hg/hgrc <<EOF
89 > [ui]
89 > [ui]
90 > verbose=True
90 > verbose=True
91 > EOF
91 > EOF
92 $ hg -R foobar st -q
92 $ hg -R foobar st -q
93
93
94 username expansion
94 username expansion
95
95
96 $ olduser=$HGUSER
96 $ olduser=$HGUSER
97 $ unset HGUSER
97 $ unset HGUSER
98
98
99 $ FAKEUSER='John Doe'
99 $ FAKEUSER='John Doe'
100 $ export FAKEUSER
100 $ export FAKEUSER
101 $ echo '[ui]' > $HGRC
101 $ echo '[ui]' > $HGRC
102 $ echo 'username = $FAKEUSER' >> $HGRC
102 $ echo 'username = $FAKEUSER' >> $HGRC
103
103
104 $ hg init usertest
104 $ hg init usertest
105 $ cd usertest
105 $ cd usertest
106 $ touch bar
106 $ touch bar
107 $ hg commit --addremove --quiet -m "added bar"
107 $ hg commit --addremove --quiet -m "added bar"
108 $ hg log --template "{author}\n"
108 $ hg log --template "{author}\n"
109 John Doe
109 John Doe
110 $ cd ..
110 $ cd ..
111
111
112 $ hg showconfig
112 $ hg showconfig
113 bundle.mainreporoot=$TESTTMP
113 bundle.mainreporoot=$TESTTMP
114 ui.username=$FAKEUSER
114 ui.username=$FAKEUSER
115
115
116 $ unset FAKEUSER
116 $ unset FAKEUSER
117 $ HGUSER=$olduser
117 $ HGUSER=$olduser
118 $ export HGUSER
118 $ export HGUSER
119
119
120 showconfig with multiple arguments
120 showconfig with multiple arguments
121
121
122 $ echo "[alias]" > $HGRC
122 $ echo "[alias]" > $HGRC
123 $ echo "log = log -g" >> $HGRC
123 $ echo "log = log -g" >> $HGRC
124 $ echo "[defaults]" >> $HGRC
124 $ echo "[defaults]" >> $HGRC
125 $ echo "identify = -n" >> $HGRC
125 $ echo "identify = -n" >> $HGRC
126 $ hg showconfig alias defaults
126 $ hg showconfig alias defaults
127 alias.log=log -g
127 alias.log=log -g
128 defaults.identify=-n
128 defaults.identify=-n
129 $ hg showconfig alias defaults.identify
129 $ hg showconfig alias defaults.identify
130 abort: only one config item permitted
130 abort: only one config item permitted
131 [255]
131 [255]
132 $ hg showconfig alias.log defaults.identify
132 $ hg showconfig alias.log defaults.identify
133 abort: only one config item permitted
133 abort: only one config item permitted
134 [255]
134 [255]
135
135
136 HGPLAIN
136 HGPLAIN
137
137
138 $ echo "[ui]" > $HGRC
138 $ echo "[ui]" > $HGRC
139 $ echo "debug=true" >> $HGRC
139 $ echo "debug=true" >> $HGRC
140 $ echo "fallbackencoding=ASCII" >> $HGRC
140 $ echo "fallbackencoding=ASCII" >> $HGRC
141 $ echo "quiet=true" >> $HGRC
141 $ echo "quiet=true" >> $HGRC
142 $ echo "slash=true" >> $HGRC
142 $ echo "slash=true" >> $HGRC
143 $ echo "traceback=true" >> $HGRC
143 $ echo "traceback=true" >> $HGRC
144 $ echo "verbose=true" >> $HGRC
144 $ echo "verbose=true" >> $HGRC
145 $ echo "style=~/.hgstyle" >> $HGRC
145 $ echo "style=~/.hgstyle" >> $HGRC
146 $ echo "logtemplate={node}" >> $HGRC
146 $ echo "logtemplate={node}" >> $HGRC
147 $ echo "[defaults]" >> $HGRC
147 $ echo "[defaults]" >> $HGRC
148 $ echo "identify=-n" >> $HGRC
148 $ echo "identify=-n" >> $HGRC
149 $ echo "[alias]" >> $HGRC
149 $ echo "[alias]" >> $HGRC
150 $ echo "log=log -g" >> $HGRC
150 $ echo "log=log -g" >> $HGRC
151
151
152 customized hgrc
152 customized hgrc
153
153
154 $ hg showconfig
154 $ hg showconfig
155 read config from: $TESTTMP/hgrc
155 read config from: $TESTTMP/hgrc
156 $TESTTMP/hgrc:13: alias.log=log -g
156 $TESTTMP/hgrc:13: alias.log=log -g
157 repo: bundle.mainreporoot=$TESTTMP
157 repo: bundle.mainreporoot=$TESTTMP
158 $TESTTMP/hgrc:11: defaults.identify=-n
158 $TESTTMP/hgrc:11: defaults.identify=-n
159 $TESTTMP/hgrc:2: ui.debug=true
159 $TESTTMP/hgrc:2: ui.debug=true
160 $TESTTMP/hgrc:3: ui.fallbackencoding=ASCII
160 $TESTTMP/hgrc:3: ui.fallbackencoding=ASCII
161 $TESTTMP/hgrc:4: ui.quiet=true
161 $TESTTMP/hgrc:4: ui.quiet=true
162 $TESTTMP/hgrc:5: ui.slash=true
162 $TESTTMP/hgrc:5: ui.slash=true
163 $TESTTMP/hgrc:6: ui.traceback=true
163 $TESTTMP/hgrc:6: ui.traceback=true
164 $TESTTMP/hgrc:7: ui.verbose=true
164 $TESTTMP/hgrc:7: ui.verbose=true
165 $TESTTMP/hgrc:8: ui.style=~/.hgstyle
165 $TESTTMP/hgrc:8: ui.style=~/.hgstyle
166 $TESTTMP/hgrc:9: ui.logtemplate={node}
166 $TESTTMP/hgrc:9: ui.logtemplate={node}
167
167
168 plain hgrc
168 plain hgrc
169
169
170 $ HGPLAIN=; export HGPLAIN
170 $ HGPLAIN=; export HGPLAIN
171 $ hg showconfig --config ui.traceback=True --debug
171 $ hg showconfig --config ui.traceback=True --debug
172 read config from: $TESTTMP/hgrc
172 read config from: $TESTTMP/hgrc
173 repo: bundle.mainreporoot=$TESTTMP
173 repo: bundle.mainreporoot=$TESTTMP
174 --config: ui.traceback=True
174 --config: ui.traceback=True
175 --verbose: ui.verbose=False
175 --verbose: ui.verbose=False
176 --debug: ui.debug=True
176 --debug: ui.debug=True
177 --quiet: ui.quiet=False
177 --quiet: ui.quiet=False
178
178
179 plain mode with exceptions
179 plain mode with exceptions
180
180
181 $ cat > plain.py <<EOF
181 $ cat > plain.py <<EOF
182 > from mercurial import commands, extensions
182 > from mercurial import commands, extensions
183 > def _config(orig, ui, repo, *values, **opts):
183 > def _config(orig, ui, repo, *values, **opts):
184 > ui.write('plain: %r\n' % ui.plain())
184 > ui.write('plain: %r\n' % ui.plain())
185 > return orig(ui, repo, *values, **opts)
185 > return orig(ui, repo, *values, **opts)
186 > def uisetup(ui):
186 > def uisetup(ui):
187 > extensions.wrapcommand(commands.table, 'config', _config)
187 > extensions.wrapcommand(commands.table, 'config', _config)
188 > EOF
188 > EOF
189 $ echo "[extensions]" >> $HGRC
189 $ echo "[extensions]" >> $HGRC
190 $ echo "plain=./plain.py" >> $HGRC
190 $ echo "plain=./plain.py" >> $HGRC
191 $ HGPLAINEXCEPT=; export HGPLAINEXCEPT
191 $ HGPLAINEXCEPT=; export HGPLAINEXCEPT
192 $ hg showconfig --config ui.traceback=True --debug
192 $ hg showconfig --config ui.traceback=True --debug
193 plain: True
193 plain: True
194 read config from: $TESTTMP/hgrc
194 read config from: $TESTTMP/hgrc
195 repo: bundle.mainreporoot=$TESTTMP
195 repo: bundle.mainreporoot=$TESTTMP
196 $TESTTMP/hgrc:15: extensions.plain=./plain.py
196 $TESTTMP/hgrc:15: extensions.plain=./plain.py
197 --config: ui.traceback=True
197 --config: ui.traceback=True
198 --verbose: ui.verbose=False
198 --verbose: ui.verbose=False
199 --debug: ui.debug=True
199 --debug: ui.debug=True
200 --quiet: ui.quiet=False
200 --quiet: ui.quiet=False
201 $ unset HGPLAIN
201 $ unset HGPLAIN
202 $ hg showconfig --config ui.traceback=True --debug
202 $ hg showconfig --config ui.traceback=True --debug
203 plain: True
203 plain: True
204 read config from: $TESTTMP/hgrc
204 read config from: $TESTTMP/hgrc
205 repo: bundle.mainreporoot=$TESTTMP
205 repo: bundle.mainreporoot=$TESTTMP
206 $TESTTMP/hgrc:15: extensions.plain=./plain.py
206 $TESTTMP/hgrc:15: extensions.plain=./plain.py
207 --config: ui.traceback=True
207 --config: ui.traceback=True
208 --verbose: ui.verbose=False
208 --verbose: ui.verbose=False
209 --debug: ui.debug=True
209 --debug: ui.debug=True
210 --quiet: ui.quiet=False
210 --quiet: ui.quiet=False
211 $ HGPLAINEXCEPT=i18n; export HGPLAINEXCEPT
211 $ HGPLAINEXCEPT=i18n; export HGPLAINEXCEPT
212 $ hg showconfig --config ui.traceback=True --debug
212 $ hg showconfig --config ui.traceback=True --debug
213 plain: True
213 plain: True
214 read config from: $TESTTMP/hgrc
214 read config from: $TESTTMP/hgrc
215 repo: bundle.mainreporoot=$TESTTMP
215 repo: bundle.mainreporoot=$TESTTMP
216 $TESTTMP/hgrc:15: extensions.plain=./plain.py
216 $TESTTMP/hgrc:15: extensions.plain=./plain.py
217 --config: ui.traceback=True
217 --config: ui.traceback=True
218 --verbose: ui.verbose=False
218 --verbose: ui.verbose=False
219 --debug: ui.debug=True
219 --debug: ui.debug=True
220 --quiet: ui.quiet=False
220 --quiet: ui.quiet=False
221
221
222 source of paths is not mangled
222 source of paths is not mangled
223
223
224 $ cat >> $HGRCPATH <<EOF
224 $ cat >> $HGRCPATH <<EOF
225 > [paths]
225 > [paths]
226 > foo = bar
226 > foo = bar
227 > EOF
227 > EOF
228 $ hg showconfig --debug paths
228 $ hg showconfig --debug paths
229 plain: True
229 plain: True
230 read config from: $TESTTMP/hgrc
230 read config from: $TESTTMP/hgrc
231 $TESTTMP/hgrc:17: paths.foo=$TESTTMP/bar (glob)
231 $TESTTMP/hgrc:17: paths.foo=$TESTTMP/bar (glob)
General Comments 0
You need to be logged in to leave comments. Login now