diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -66,7 +66,7 @@ def walkchangerevs(ui, repo, pats, opts)
window, we first walk forwards to gather data, then in the desired
order (usually backwards) to display it.
- This function returns an (iterator, getchange) pair. The
+ This function returns an (iterator, getchange, matchfn) tuple. The
getchange function returns the changelog entry for a numeric
revision. The iterator yields 3-tuples. They will be of one of
the following forms:
@@ -82,10 +82,11 @@ def walkchangerevs(ui, repo, pats, opts)
"iter", rev, None: in-order traversal of the revs earlier iterated
over with "add" - use to display data'''
+ files, matchfn, anypats, cwd = matchpats(repo, pats, opts)
+
if repo.changelog.count() == 0:
- return [], False
+ return [], False, matchfn
- files, matchfn, anypats, cwd = matchpats(repo, pats, opts)
revs = map(int, revrange(ui, repo, opts['rev'] or ['tip:0']))
wanted = {}
slowpath = anypats
@@ -153,7 +154,7 @@ def walkchangerevs(ui, repo, pats, opts)
yield 'add', rev, fns
for rev in nrevs:
yield 'iter', rev, None
- return iterate(), getchange
+ return iterate(), getchange, matchfn
revrangesep = ':'
@@ -1117,9 +1118,12 @@ def diff(ui, repo, *pats, **opts):
def doexport(ui, repo, changeset, seqno, total, revwidth, opts):
node = repo.lookup(changeset)
- prev, other = repo.changelog.parents(node)
+ parents = [p for p in repo.changelog.parents(node) if p != nullid]
+ prev = (parents and parents[0]) or nullid
change = repo.changelog.read(node)
+ if opts['switch_parent']:
+ parents.reverse()
fp = make_file(repo, repo.changelog, opts['output'],
node=node, total=total, seqno=seqno,
revwidth=revwidth)
@@ -1130,8 +1134,8 @@ def doexport(ui, repo, changeset, seqno,
fp.write("# User %s\n" % change[1])
fp.write("# Node ID %s\n" % hex(node))
fp.write("# Parent %s\n" % hex(prev))
- if other != nullid:
- fp.write("# Parent %s\n" % hex(other))
+ if len(parents) > 1:
+ fp.write("# Parent %s\n" % hex(parents[1]))
fp.write(change[4].rstrip())
fp.write("\n\n")
@@ -1162,6 +1166,9 @@ def export(ui, repo, *changesets, **opts
Without the -a option, export will avoid generating diffs of files
it detects as binary. With -a, export will generate a diff anyway,
probably with undesirable results.
+
+ With the --switch-parent option, the diff will be against the second
+ parent. It can be useful to review a merge.
"""
if not changesets:
raise util.Abort(_("export requires at least one changeset"))
@@ -1281,7 +1288,7 @@ def grep(ui, repo, pattern, *pats, **opt
fstate = {}
skip = {}
- changeiter, getchange = walkchangerevs(ui, repo, pats, opts)
+ changeiter, getchange, matchfn = walkchangerevs(ui, repo, pats, opts)
count = 0
incrementing = False
for st, rev, fns in changeiter:
@@ -1544,7 +1551,7 @@ def log(ui, repo, *pats, **opts):
self.write(*args)
def __getattr__(self, key):
return getattr(self.ui, key)
- changeiter, getchange = walkchangerevs(ui, repo, pats, opts)
+ changeiter, getchange, matchfn = walkchangerevs(ui, repo, pats, opts)
for st, rev, fns in changeiter:
if st == 'window':
du = dui(ui)
@@ -1560,7 +1567,7 @@ def log(ui, repo, *pats, **opts):
br = None
if opts['keyword']:
- changes = repo.changelog.read(repo.changelog.node(rev))
+ changes = getchange(rev)
miss = 0
for k in [kw.lower() for kw in opts['keyword']]:
if not (k in changes[1].lower() or
@@ -1577,7 +1584,7 @@ def log(ui, repo, *pats, **opts):
show_changeset(du, repo, rev, brinfo=br)
if opts['patch']:
prev = (parents and parents[0]) or nullid
- dodiff(du, du, repo, prev, changenode, fns)
+ dodiff(du, du, repo, prev, changenode, match=matchfn)
du.write("\n\n")
elif st == 'iter':
for args in du.hunk[rev]:
@@ -2122,7 +2129,8 @@ def undo(ui, repo):
"""
repo.undo()
-def update(ui, repo, node=None, merge=False, clean=False, branch=None):
+def update(ui, repo, node=None, merge=False, clean=False, force=None,
+ branch=None):
"""update or merge working directory
Update the working directory to the specified revision.
@@ -2159,7 +2167,7 @@ def update(ui, repo, node=None, merge=Fa
return 1
else:
node = node and repo.lookup(node) or repo.changelog.tip()
- return repo.update(node, allow=merge, force=clean)
+ return repo.update(node, allow=merge, force=clean, forcemerge=force)
def verify(ui, repo):
"""verify the integrity of the repository
@@ -2256,7 +2264,8 @@ table = {
"^export":
(export,
[('o', 'output', "", _('print output to file with formatted name')),
- ('a', 'text', None, _('treat all files as text'))],
+ ('a', 'text', None, _('treat all files as text')),
+ ('', 'switch-parent', None, _('diff against the second parent'))],
"hg export [-a] [-o OUTFILE] REV..."),
"forget":
(forget,
@@ -2404,8 +2413,9 @@ table = {
(update,
[('b', 'branch', "", _('checkout the head of a specific branch')),
('m', 'merge', None, _('allow merging of branches')),
- ('C', 'clean', None, _('overwrite locally modified files'))],
- _('hg update [-b TAG] [-m] [-C] [REV]')),
+ ('C', 'clean', None, _('overwrite locally modified files')),
+ ('f', 'force', None, _('force a merge with outstanding changes'))],
+ _('hg update [-b TAG] [-m] [-C] [-f] [REV]')),
"verify": (verify, [], _('hg verify')),
"version": (show_version, [], _('hg version')),
}
diff --git a/mercurial/hgweb.py b/mercurial/hgweb.py
--- a/mercurial/hgweb.py
+++ b/mercurial/hgweb.py
@@ -632,6 +632,8 @@ class hgweb(object):
for k,n in i:
yield {"parity": parity,
"tag": k,
+ "tagmanifest": hex(cl.read(n)[0]),
+ "date": cl.read(n)[2],
"node": hex(n)}
parity = 1 - parity
@@ -639,6 +641,76 @@ class hgweb(object):
manifest=hex(mf),
entries=entries)
+ def summary(self):
+ cl = self.repo.changelog
+ mf = cl.read(cl.tip())[0]
+
+ i = self.repo.tagslist()
+ i.reverse()
+
+ def tagentries(**map):
+ parity = 0
+ count = 0
+ for k,n in i:
+ if k == "tip": # skip tip
+ continue;
+
+ count += 1
+ if count > 10: # limit to 10 tags
+ break;
+
+ c = cl.read(n)
+ m = c[0]
+ t = c[2]
+
+ yield self.t("tagentry",
+ parity = parity,
+ tag = k,
+ node = hex(n),
+ date = t,
+ tagmanifest = hex(m))
+ parity = 1 - parity
+
+ def changelist(**map):
+ parity = 0
+ cl = self.repo.changelog
+ l = [] # build a list in forward order for efficiency
+ for i in range(start, end):
+ n = cl.node(i)
+ changes = cl.read(n)
+ hn = hex(n)
+ t = changes[2]
+
+ l.insert(0, self.t(
+ 'shortlogentry',
+ parity = parity,
+ author = changes[1],
+ manifest = hex(changes[0]),
+ desc = changes[4],
+ date = t,
+ rev = i,
+ node = hn))
+ parity = 1 - parity
+
+ yield l
+
+ cl = self.repo.changelog
+ mf = cl.read(cl.tip())[0]
+ count = cl.count()
+ start = max(0, count - self.maxchanges)
+ end = min(count, start + self.maxchanges)
+ pos = end - 1
+
+ yield self.t("summary",
+ desc = self.repo.ui.config("web", "description", "unknown"),
+ owner = (self.repo.ui.config("ui", "username") or # preferred
+ self.repo.ui.config("web", "contact") or # deprecated
+ self.repo.ui.config("web", "author", "unknown")), # also
+ lastchange = (0, 0), # FIXME
+ manifest = hex(mf),
+ tags = tagentries,
+ shortlog = changelist)
+
def filediff(self, file, changeset):
cl = self.repo.changelog
n = self.repo.lookup(changeset)
@@ -798,6 +870,9 @@ class hgweb(object):
elif req.form['cmd'][0] == 'tags':
req.write(self.tags())
+ elif req.form['cmd'][0] == 'summary':
+ req.write(self.summary())
+
elif req.form['cmd'][0] == 'filediff':
req.write(self.filediff(req.form['file'][0], req.form['node'][0]))
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -1364,7 +1364,7 @@ class localrepository(object):
return
def update(self, node, allow=False, force=False, choose=None,
- moddirstate=True):
+ moddirstate=True, forcemerge=False):
pl = self.dirstate.parents()
if not force and pl[1] != nullid:
self.ui.warn(_("aborting: outstanding uncommitted merges\n"))
@@ -1384,6 +1384,18 @@ class localrepository(object):
(c, a, d, u) = self.changes()
+ if allow and not forcemerge:
+ if c or a or d:
+ raise util.Abort(_("outstanding uncommited changes"))
+ if not forcemerge and not force:
+ for f in u:
+ if f in m2:
+ t1 = self.wread(f)
+ t2 = self.file(f).read(m2[f])
+ if cmp(t1, t2) != 0:
+ raise util.Abort(_("'%s' already exists in the working"
+ " dir and differs from remote") % f)
+
# is this a jump, or a merge? i.e. is there a linear path
# from p1 to p2?
linear_path = (pa == p1 or pa == p2)
diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -145,7 +145,7 @@ class ui(object):
os.environ.get("EDITOR", "vi"))
os.environ["HGUSER"] = self.username()
- util.system("%s %s" % (editor, name), errprefix=_("edit failed"))
+ util.system("%s \"%s\"" % (editor, name), errprefix=_("edit failed"))
t = open(name).read()
t = re.sub("(?m)^HG:.*\n", "", t)
diff --git a/templates/changelog-gitweb.tmpl b/templates/changelog-gitweb.tmpl
new file mode 100644
--- /dev/null
+++ b/templates/changelog-gitweb.tmpl
@@ -0,0 +1,30 @@
+#header#
+
#repo|escape#: Changelog
+
+
+
+
+
+
+
+
+
+
+
summary | changelog |
tags |
manifest
+
+#changenav%naventry#
+
+
+#entries%changelogentry#
+
+#footer#
diff --git a/templates/changelogentry-gitweb.tmpl b/templates/changelogentry-gitweb.tmpl
new file mode 100644
--- /dev/null
+++ b/templates/changelogentry-gitweb.tmpl
@@ -0,0 +1,14 @@
+
+
+
+
#author|obfuscate# [#date|rfc822date#]
+
+
+#desc|addbreaks#
+
+
+
diff --git a/templates/changeset-gitweb.tmpl b/templates/changeset-gitweb.tmpl
new file mode 100644
--- /dev/null
+++ b/templates/changeset-gitweb.tmpl
@@ -0,0 +1,40 @@
+#header#
+#repo|escape#: Changeset
+
+
+
+
+
+
+
+
+
+
+
+author | #author|obfuscate# |
+ | #date|date# (#date|age# ago) |
+changeset | #node|short# |
+manifest | #manifest|short# |
+#parent%changesetparent#
+#changesettag#
+
+
+
+#desc|addbreaks#
+
+
+
+
+#diff#
+
+#footer#
diff --git a/templates/error-gitweb.tmpl b/templates/error-gitweb.tmpl
new file mode 100644
--- /dev/null
+++ b/templates/error-gitweb.tmpl
@@ -0,0 +1,12 @@
+#header#
+
+
+
+
+Error parsing query string
+
+
+
+#footer#
diff --git a/templates/fileannotate-gitweb.tmpl b/templates/fileannotate-gitweb.tmpl
new file mode 100644
--- /dev/null
+++ b/templates/fileannotate-gitweb.tmpl
@@ -0,0 +1,43 @@
+#header#
+#repo|escape#: Annotate
+
+
+
+
+
+
+
+
+#file#
+
+
+
+ changeset #rev#: |
+ #node|short# |
+#parent%fileannotateparent#
+
+ manifest: |
+ #manifest|short# |
+
+ author: |
+ #author|obfuscate# |
+
+ date: |
+ #date|date# (#date|age# ago) |
+
+ permissions: |
+ #permissions|permissions# |
+
+
+
+
+#annotate%annotateline#
+
+
+
+#footer#
diff --git a/templates/filelog-gitweb.tmpl b/templates/filelog-gitweb.tmpl
new file mode 100644
--- /dev/null
+++ b/templates/filelog-gitweb.tmpl
@@ -0,0 +1,20 @@
+#header#
+#repo|escape#: Manifest
+
+
+
+
+
+
+
+
+
+#entries%filelogentry#
+
+
+#footer#
diff --git a/templates/filerevision-gitweb.tmpl b/templates/filerevision-gitweb.tmpl
new file mode 100644
--- /dev/null
+++ b/templates/filerevision-gitweb.tmpl
@@ -0,0 +1,41 @@
+#header#
+#repo|escape#: File revision
+
+
+
+
+
+
+
+
+#file#
+
+
+
+ changeset #rev#: |
+ #node|short# |
+#parent%fileannotateparent#
+
+ manifest: |
+ #manifest|short# |
+
+ author: |
+ #author|obfuscate# |
+
+ date: |
+ #date|date# (#date|age# ago) |
+
+ permissions: |
+ #permissions|permissions# |
+
+
+
+#text%fileline#
+
+
+#footer#
diff --git a/templates/footer-gitweb.tmpl b/templates/footer-gitweb.tmpl
new file mode 100644
--- /dev/null
+++ b/templates/footer-gitweb.tmpl
@@ -0,0 +1,6 @@
+
+
+