mercurial/commands.py
changeset 255 20a44c82795f
parent 254 c03f58e5fd2d
child 257 65dccc4555c2
equal deleted inserted replaced
254:c03f58e5fd2d 255:20a44c82795f
    66         to = repo.file(f).read(mmap[f])
    66         to = repo.file(f).read(mmap[f])
    67         tn = ""
    67         tn = ""
    68         sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
    68         sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
    69     
    69     
    70 def help(ui, cmd=None):
    70 def help(ui, cmd=None):
    71     '''show help'''
    71     '''show help for a given command or all commands'''
    72     if cmd:
    72     if cmd:
    73         try:
    73         try:
    74             i = find(cmd)
    74             i = find(cmd)
    75             ui.write("%s\n\n" % i[2])
    75             ui.write("%s\n\n" % i[2])
    76             ui.write(i[0].__doc__, "\n")
    76             ui.write(i[0].__doc__, "\n")
    77         except UnknownCommand:
    77         except UnknownCommand:
    78             ui.warn("unknown command %s" % cmd)
    78             ui.warn("unknown command %s" % cmd)
    79         sys.exit(0)
    79         sys.exit(0)
    80     
    80     else:
    81     ui.status("""\
    81         ui.status('hg commands:\n\n')
    82  hg commands:
    82 
    83 
    83         h = {}
    84  add [files...]        add the given files in the next commit
    84         for e in table.values():
    85  addremove             add all new files, delete all missing files
    85             f = e[0]
    86  annotate [files...]   show changeset number per file line
    86             if f.__name__.startswith("debug"): continue
    87  branch <path>         create a branch of <path> in this directory
    87             d = ""
    88  checkout [changeset]  checkout the latest or given changeset
    88             if f.__doc__:
    89  commit                commit all changes to the repository
    89                 d = f.__doc__.splitlines(0)[0].rstrip()
    90  diff [files...]       diff working directory (or selected files)
    90             h[f.__name__] = d
    91  dump <file> [rev]     dump the latest or given revision of a file
    91 
    92  dumpmanifest [rev]    dump the latest or given revision of the manifest
    92         fns = h.keys()
    93  export <rev>          dump the changeset header and diffs for a revision
    93         fns.sort()
    94  history               show changeset history
    94         m = max(map(len, fns))
    95  init                  create a new repository in this directory
    95         for f in fns:
    96  log <file>            show revision history of a single file
    96             ui.status(' %-*s   %s\n' % (m, f, h[f]))
    97  merge <path>          merge changes from <path> into local repository
    97 
    98  recover               rollback an interrupted transaction
    98 # Commands start here, listed alphabetically
    99  remove [files...]     remove the given files in the next commit
       
   100  serve                 export the repository via HTTP
       
   101  status                show new, missing, and changed files in working dir
       
   102  tags                  show current changeset tags
       
   103  undo                  undo the last transaction
       
   104 """)
       
   105 
    99 
   106 def add(ui, repo, file, *files):
   100 def add(ui, repo, file, *files):
   107     '''add the specified files on the next commit'''
   101     '''add the specified files on the next commit'''
   108     repo.add(relpath(repo, (file,) + files))
   102     repo.add(relpath(repo, (file,) + files))
   109 
   103 
   110 def addremove(ui, repo):
   104 def addremove(ui, repo):
       
   105     """add all new files, delete all missing files"""
   111     (c, a, d, u) = repo.diffdir(repo.root)
   106     (c, a, d, u) = repo.diffdir(repo.root)
   112     repo.add(a)
   107     repo.add(a)
   113     repo.remove(d)
   108     repo.remove(d)
   114 
   109 
   115 def annotate(u, repo, file, *files, **ops):
   110 def annotate(u, repo, file, *files, **ops):
       
   111     """show changeset information per file line"""
   116     def getnode(rev):
   112     def getnode(rev):
   117         return hg.short(repo.changelog.node(rev))
   113         return hg.short(repo.changelog.node(rev))
   118 
   114 
   119     def getname(rev):
   115     def getname(rev):
   120         try:
   116         try:
   157     '''branch from a local repository'''
   153     '''branch from a local repository'''
   158     # this should eventually support remote repos
   154     # this should eventually support remote repos
   159     os.system("cp -al %s/.hg .hg" % path)
   155     os.system("cp -al %s/.hg .hg" % path)
   160 
   156 
   161 def cat(ui, repo, file, rev = []):
   157 def cat(ui, repo, file, rev = []):
       
   158     """output the latest or given revision of a file"""
   162     r = repo.file(file)
   159     r = repo.file(file)
   163     n = r.tip()
   160     n = r.tip()
   164     if rev: n = r.lookup(rev)
   161     if rev: n = r.lookup(rev)
   165     sys.stdout.write(r.read(n))
   162     sys.stdout.write(r.read(n))
   166 
   163 
   196         if e[5] != hg.nullid:
   193         if e[5] != hg.nullid:
   197             print "\t%d -> %d" % (r.rev(e[5]), i)
   194             print "\t%d -> %d" % (r.rev(e[5]), i)
   198     print "}"
   195     print "}"
   199 
   196 
   200 def diff(ui, repo, *files, **opts):
   197 def diff(ui, repo, *files, **opts):
       
   198     """diff working directory (or selected files)"""
   201     revs = []
   199     revs = []
   202     if opts['rev']:
   200     if opts['rev']:
   203         revs = map(lambda x: repo.lookup(x), opts['rev'])
   201         revs = map(lambda x: repo.lookup(x), opts['rev'])
   204     
   202     
   205     if len(revs) > 2:
   203     if len(revs) > 2:
   212         files = relpath(repo, [""])
   210         files = relpath(repo, [""])
   213 
   211 
   214     dodiff(repo, files, *revs)
   212     dodiff(repo, files, *revs)
   215 
   213 
   216 def export(ui, repo, changeset):
   214 def export(ui, repo, changeset):
       
   215     """dump the changeset header and diffs for a revision"""
   217     node = repo.lookup(changeset)
   216     node = repo.lookup(changeset)
   218     prev, other = repo.changelog.parents(node)
   217     prev, other = repo.changelog.parents(node)
   219     change = repo.changelog.read(node)
   218     change = repo.changelog.read(node)
   220     print "# HG changeset patch"
   219     print "# HG changeset patch"
   221     print "# User %s" % change[1]
   220     print "# User %s" % change[1]
   271             time.localtime(float(changes[2].split(' ')[0])))
   270             time.localtime(float(changes[2].split(' ')[0])))
   272         if ui.verbose: print "files:", " ".join(changes[3])
   271         if ui.verbose: print "files:", " ".join(changes[3])
   273         print "description:"
   272         print "description:"
   274         print changes[4]
   273         print changes[4]
   275 
   274 
   276 def patch(ui, repo, patches, opts):
       
   277     """import an ordered set of patches"""
       
   278     try:
       
   279         import psyco
       
   280         psyco.full()
       
   281     except:
       
   282         pass
       
   283     
       
   284     d = opts["base"]
       
   285     strip = opts["strip"]
       
   286     quiet = opts["quiet"] and "> /dev/null" or ""
       
   287 
       
   288     for patch in patches:
       
   289         ui.status("applying %s\n" % patch)
       
   290         pf = os.path.join(d, patch)
       
   291 
       
   292         text = ""
       
   293         for l in file(pf):
       
   294             if l[:4] == "--- ": break
       
   295             text += l
       
   296 
       
   297         f = os.popen("lsdiff --strip %d %s" % (strip, pf))
       
   298         files = filter(None, map(lambda x: x.rstrip(), f.read().splitlines()))
       
   299         f.close()
       
   300 
       
   301         if files:
       
   302             if os.system("patch -p%d < %s %s" % (strip, pf, quiet)):
       
   303                 raise "patch failed!"
       
   304         repo.commit(files, text)
       
   305 
       
   306 def init(ui):
   275 def init(ui):
   307     """create a repository"""
   276     """create a repository"""
   308     hg.repository(ui, ".", create=1)
   277     hg.repository(ui, ".", create=1)
   309 
   278 
   310 def log(ui, repo, f):
   279 def log(ui, repo, f):
       
   280     """show the revision history of a single file"""
   311     f = relpath(repo, [f])[0]
   281     f = relpath(repo, [f])[0]
   312 
   282 
   313     r = repo.file(f)
   283     r = repo.file(f)
   314     for i in range(r.count()):
   284     for i in range(r.count()):
   315         n = r.node(i)
   285         n = r.node(i)
   329         print "description:"
   299         print "description:"
   330         print changes[4].rstrip()
   300         print changes[4].rstrip()
   331         print
   301         print
   332 
   302 
   333 def manifest(ui, repo, rev = []):
   303 def manifest(ui, repo, rev = []):
       
   304     """output the latest or given revision of the project manifest"""
   334     n = repo.manifest.tip()
   305     n = repo.manifest.tip()
   335     if rev:
   306     if rev:
   336         n = repo.manifest.lookup(rev)
   307         n = repo.manifest.lookup(rev)
   337     m = repo.manifest.read(n)
   308     m = repo.manifest.read(n)
   338     files = m.keys()
   309     files = m.keys()
   349         p = repo.dirstate.parents()
   320         p = repo.dirstate.parents()
   350 
   321 
   351     for n in p:
   322     for n in p:
   352         if n != hg.nullid:
   323         if n != hg.nullid:
   353             ui.write("%d:%s\n" % (repo.changelog.rev(n), hg.hex(n)))
   324             ui.write("%d:%s\n" % (repo.changelog.rev(n), hg.hex(n)))
       
   325 
       
   326 def patch(ui, repo, patches, opts):
       
   327     """import an ordered set of patches"""
       
   328     try:
       
   329         import psyco
       
   330         psyco.full()
       
   331     except:
       
   332         pass
       
   333     
       
   334     d = opts["base"]
       
   335     strip = opts["strip"]
       
   336     quiet = opts["quiet"] and "> /dev/null" or ""
       
   337 
       
   338     for patch in patches:
       
   339         ui.status("applying %s\n" % patch)
       
   340         pf = os.path.join(d, patch)
       
   341 
       
   342         text = ""
       
   343         for l in file(pf):
       
   344             if l[:4] == "--- ": break
       
   345             text += l
       
   346 
       
   347         f = os.popen("lsdiff --strip %d %s" % (strip, pf))
       
   348         files = filter(None, map(lambda x: x.rstrip(), f.read().splitlines()))
       
   349         f.close()
       
   350 
       
   351         if files:
       
   352             if os.system("patch -p%d < %s %s" % (strip, pf, quiet)):
       
   353                 raise "patch failed!"
       
   354         repo.commit(files, text)
   354 
   355 
   355 def pull(ui, repo, source):
   356 def pull(ui, repo, source):
   356     """pull changes from the specified source"""
   357     """pull changes from the specified source"""
   357     paths = {}
   358     paths = {}
   358     try:
   359     try:
   385         files += open(rc['files']).read().splitlines()
   386         files += open(rc['files']).read().splitlines()
   386         
   387         
   387     repo.rawcommit(files, text, rc['user'], rc['date'], *rc['parent'])
   388     repo.rawcommit(files, text, rc['user'], rc['date'], *rc['parent'])
   388  
   389  
   389 def recover(ui, repo):
   390 def recover(ui, repo):
       
   391     """roll back an interrupted transaction"""
   390     repo.recover()
   392     repo.recover()
   391 
   393 
   392 def remove(ui, repo, file, *files):
   394 def remove(ui, repo, file, *files):
   393     """remove the specified files on the next commit"""
   395     """remove the specified files on the next commit"""
   394     repo.remove(relpath(repo, (file,) + files))
   396     repo.remove(relpath(repo, (file,) + files))
   395 
   397 
   396 def serve(ui, repo, **opts):
   398 def serve(ui, repo, **opts):
       
   399     """export the repository via HTTP"""
   397     from mercurial import hgweb
   400     from mercurial import hgweb
   398     hgweb.server(repo.root, opts["name"], opts["templates"],
   401     hgweb.server(repo.root, opts["name"], opts["templates"],
   399                  opts["address"], opts["port"])
   402                  opts["address"], opts["port"])
   400     
   403     
   401 def status(ui, repo):
   404 def status(ui, repo):
   413     for f in a: print "A", f
   416     for f in a: print "A", f
   414     for f in d: print "R", f
   417     for f in d: print "R", f
   415     for f in u: print "?", f
   418     for f in u: print "?", f
   416 
   419 
   417 def tags(ui, repo):
   420 def tags(ui, repo):
       
   421     """list repository tags"""
   418     repo.lookup(0) # prime the cache
   422     repo.lookup(0) # prime the cache
   419     i = repo.tags.items()
   423     i = repo.tags.items()
   420     i.sort()
   424     i.sort()
   421     for k, n in i:
   425     for k, n in i:
   422         try:
   426         try:
   424         except KeyError:
   428         except KeyError:
   425             r = "?"
   429             r = "?"
   426         print "%-30s %5d:%s" % (k, repo.changelog.rev(n), hg.hex(n))
   430         print "%-30s %5d:%s" % (k, repo.changelog.rev(n), hg.hex(n))
   427 
   431 
   428 def tip(ui, repo):
   432 def tip(ui, repo):
       
   433     """show the tip revision"""
   429     n = repo.changelog.tip()
   434     n = repo.changelog.tip()
   430     t = repo.changelog.rev(n)
   435     t = repo.changelog.rev(n)
   431     ui.status("%d:%s\n" % (t, hg.hex(n)))
   436     ui.status("%d:%s\n" % (t, hg.hex(n)))
   432 
   437 
   433 def undo(ui, repo):
   438 def undo(ui, repo):
       
   439     """undo the last transaction"""
   434     repo.undo()
   440     repo.undo()
   435 
   441 
   436 def update(ui, repo, node=None):
   442 def update(ui, repo, node=None):
   437     '''update or merge working directory
   443     '''update or merge working directory
   438 
   444 
   450     repo.update(node)
   456     repo.update(node)
   451 
   457 
   452 def verify(ui, repo):
   458 def verify(ui, repo):
   453     """verify the integrity of the repository"""
   459     """verify the integrity of the repository"""
   454     return repo.verify()
   460     return repo.verify()
       
   461 
       
   462 # Command options and aliases are listed here, alphabetically
   455 
   463 
   456 table = {
   464 table = {
   457     "add": (add, [], "hg add [files]"),
   465     "add": (add, [], "hg add [files]"),
   458     "addremove": (addremove, [], "hg addremove"),
   466     "addremove": (addremove, [], "hg addremove"),
   459     "ann|annotate": (annotate,
   467     "ann|annotate": (annotate,