Show More
@@ -164,18 +164,6 b' def cat(ui, repo, file, rev = []):' | |||||
164 | if rev: n = r.lookup(rev) |
|
164 | if rev: n = r.lookup(rev) | |
165 | sys.stdout.write(r.read(n)) |
|
165 | sys.stdout.write(r.read(n)) | |
166 |
|
166 | |||
167 | def checkout(ui, repo, changeset=None): |
|
|||
168 | '''checkout a given changeset or the current tip''' |
|
|||
169 | (c, a, d, u) = repo.diffdir(repo.root) |
|
|||
170 | if c or a or d: |
|
|||
171 | ui.warn("aborting (outstanding changes in working directory)\n") |
|
|||
172 | sys.exit(1) |
|
|||
173 |
|
||||
174 | node = repo.changelog.tip() |
|
|||
175 | if changeset: |
|
|||
176 | node = repo.lookup(changeset) |
|
|||
177 | repo.checkout(node) |
|
|||
178 |
|
||||
179 | def commit(ui, repo, *files): |
|
167 | def commit(ui, repo, *files): | |
180 | """commit the specified files or all outstanding changes""" |
|
168 | """commit the specified files or all outstanding changes""" | |
181 | repo.commit(relpath(repo, files)) |
|
169 | repo.commit(relpath(repo, files)) | |
@@ -405,14 +393,6 b' def remove(ui, repo, file, *files):' | |||||
405 | """remove the specified files on the next commit""" |
|
393 | """remove the specified files on the next commit""" | |
406 | repo.remove(relpath(repo, (file,) + files)) |
|
394 | repo.remove(relpath(repo, (file,) + files)) | |
407 |
|
395 | |||
408 | def resolve(ui, repo, node=None): |
|
|||
409 | '''merge a given node or the current tip into the working dir''' |
|
|||
410 | if not node: |
|
|||
411 | node = repo.changelog.tip() |
|
|||
412 | else: |
|
|||
413 | node = repo.lookup(node) |
|
|||
414 | repo.resolve(node) |
|
|||
415 |
|
||||
416 | def serve(ui, repo, **opts): |
|
396 | def serve(ui, repo, **opts): | |
417 | from mercurial import hgweb |
|
397 | from mercurial import hgweb | |
418 | hgweb.server(repo.root, opts["name"], opts["templates"], |
|
398 | hgweb.server(repo.root, opts["name"], opts["templates"], | |
@@ -453,6 +433,22 b' def tip(ui, repo):' | |||||
453 | def undo(ui, repo): |
|
433 | def undo(ui, repo): | |
454 | repo.undo() |
|
434 | repo.undo() | |
455 |
|
435 | |||
|
436 | def update(ui, repo, node=None): | |||
|
437 | '''update or merge working directory | |||
|
438 | ||||
|
439 | If there are no outstanding changes in the working directory and | |||
|
440 | there is a linear relationship between the current version and the | |||
|
441 | requested version, the result is the requested version. | |||
|
442 | ||||
|
443 | Otherwise the result is a merge between the contents of the | |||
|
444 | current working directory and the requested version. Files that | |||
|
445 | changed between either parent are marked as changed for the next | |||
|
446 | commit and a commit must be performed before any further updates | |||
|
447 | are allowed. | |||
|
448 | ''' | |||
|
449 | node = node and repo.lookup(node) or repo.changelog.tip() | |||
|
450 | repo.update(node) | |||
|
451 | ||||
456 | def verify(ui, repo): |
|
452 | def verify(ui, repo): | |
457 | """verify the integrity of the repository""" |
|
453 | """verify the integrity of the repository""" | |
458 | return repo.verify() |
|
454 | return repo.verify() | |
@@ -468,7 +464,6 b' table = {' | |||||
468 | 'hg annotate [-u] [-c] [-n] [-r id] [files]'), |
|
464 | 'hg annotate [-u] [-c] [-n] [-r id] [files]'), | |
469 | "branch|clone": (branch, [], 'hg branch [path]'), |
|
465 | "branch|clone": (branch, [], 'hg branch [path]'), | |
470 | "cat|dump": (cat, [], 'hg cat <file> [rev]'), |
|
466 | "cat|dump": (cat, [], 'hg cat <file> [rev]'), | |
471 | "checkout|co": (checkout, [], 'hg checkout [changeset]'), |
|
|||
472 | "commit|ci": (commit, [], 'hg commit [files]'), |
|
467 | "commit|ci": (commit, [], 'hg commit [files]'), | |
473 | "debugaddchangegroup": (debugaddchangegroup, [], 'debugaddchangegroup'), |
|
468 | "debugaddchangegroup": (debugaddchangegroup, [], 'debugaddchangegroup'), | |
474 | "debugchangegroup": (debugchangegroup, [], 'debugchangegroup [roots]'), |
|
469 | "debugchangegroup": (debugchangegroup, [], 'debugchangegroup [roots]'), | |
@@ -501,7 +496,6 b' table = {' | |||||
501 | 'hg rawcommit [options] [files]'), |
|
496 | 'hg rawcommit [options] [files]'), | |
502 | "recover": (recover, [], "hg recover"), |
|
497 | "recover": (recover, [], "hg recover"), | |
503 | "remove": (remove, [], "hg remove [files]"), |
|
498 | "remove": (remove, [], "hg remove [files]"), | |
504 | "resolve": (resolve, [], 'hg resolve [node]'), |
|
|||
505 | "serve": (serve, [('p', 'port', 8000, 'listen port'), |
|
499 | "serve": (serve, [('p', 'port', 8000, 'listen port'), | |
506 | ('a', 'address', '', 'interface address'), |
|
500 | ('a', 'address', '', 'interface address'), | |
507 | ('n', 'name', os.getcwd(), 'repository name'), |
|
501 | ('n', 'name', os.getcwd(), 'repository name'), | |
@@ -511,6 +505,7 b' table = {' | |||||
511 | "tags": (tags, [], 'hg tags'), |
|
505 | "tags": (tags, [], 'hg tags'), | |
512 | "tip": (tip, [], 'hg tip'), |
|
506 | "tip": (tip, [], 'hg tip'), | |
513 | "undo": (undo, [], 'hg undo'), |
|
507 | "undo": (undo, [], 'hg undo'), | |
|
508 | "update|up|checkout|co|resolve": (update, [], 'hg update [node]'), | |||
514 | "verify": (verify, [], 'hg verify'), |
|
509 | "verify": (verify, [], 'hg verify'), | |
515 | } |
|
510 | } | |
516 |
|
511 |
@@ -327,11 +327,17 b' class localrepository:' | |||||
327 | if self.tags is None: |
|
327 | if self.tags is None: | |
328 | self.tags = {} |
|
328 | self.tags = {} | |
329 | try: |
|
329 | try: | |
|
330 | # read each head of the tags file, ending with the tip | |||
|
331 | # and add each tag found to the map, with "newer" ones | |||
|
332 | # taking precedence | |||
330 | fl = self.file(".hgtags") |
|
333 | fl = self.file(".hgtags") | |
331 | for l in fl.revision(fl.tip()).splitlines(): |
|
334 | h = fl.heads() | |
332 |
|
|
335 | h.reverse() | |
333 | n, k = l.split(" ") |
|
336 | for r in h: | |
334 | self.tags[k] = bin(n) |
|
337 | for l in fl.revision(r).splitlines(): | |
|
338 | if l: | |||
|
339 | n, k = l.split(" ") | |||
|
340 | self.tags[k] = bin(n) | |||
335 | except KeyError: pass |
|
341 | except KeyError: pass | |
336 | try: |
|
342 | try: | |
337 | return self.tags[key] |
|
343 | return self.tags[key] | |
@@ -476,27 +482,6 b' class localrepository:' | |||||
476 | self.dirstate.update(new, "n") |
|
482 | self.dirstate.update(new, "n") | |
477 | self.dirstate.forget(remove) |
|
483 | self.dirstate.forget(remove) | |
478 |
|
484 | |||
479 | def checkout(self, node): |
|
|||
480 | # checkout is really dumb at the moment |
|
|||
481 | # it ought to basically merge |
|
|||
482 | change = self.changelog.read(node) |
|
|||
483 | l = self.manifest.read(change[0]).items() |
|
|||
484 | l.sort() |
|
|||
485 |
|
||||
486 | for f,n in l: |
|
|||
487 | if f[0] == "/": continue |
|
|||
488 | self.ui.note(f, "\n") |
|
|||
489 | t = self.file(f).revision(n) |
|
|||
490 | try: |
|
|||
491 | file(self.wjoin(f), "w").write(t) |
|
|||
492 | except IOError: |
|
|||
493 | os.makedirs(os.path.dirname(f)) |
|
|||
494 | file(self.wjoin(f), "w").write(t) |
|
|||
495 |
|
||||
496 | self.dirstate.setparents(node) |
|
|||
497 | self.dirstate.clear() |
|
|||
498 | self.dirstate.update([f for f,n in l], "n") |
|
|||
499 |
|
||||
500 | def diffdir(self, path, changeset = None): |
|
485 | def diffdir(self, path, changeset = None): | |
501 | changed = [] |
|
486 | changed = [] | |
502 | added = [] |
|
487 | added = [] | |
@@ -848,10 +833,10 b' class localrepository:' | |||||
848 | tr.close() |
|
833 | tr.close() | |
849 | return |
|
834 | return | |
850 |
|
835 | |||
851 |
def |
|
836 | def update(self, node): | |
852 | pl = self.dirstate.parents() |
|
837 | pl = self.dirstate.parents() | |
853 | if pl[1] != nullid: |
|
838 | if pl[1] != nullid: | |
854 |
self.ui.warn(" |
|
839 | self.ui.warn("aborting: outstanding uncommitted merges\n") | |
855 | return |
|
840 | return | |
856 |
|
841 | |||
857 | p1, p2 = pl[0], node |
|
842 | p1, p2 = pl[0], node | |
@@ -866,7 +851,7 b' class localrepository:' | |||||
866 |
|
851 | |||
867 | # resolve the manifest to determine which files |
|
852 | # resolve the manifest to determine which files | |
868 | # we care about merging |
|
853 | # we care about merging | |
869 |
self.ui. |
|
854 | self.ui.note("resolving manifests\n") | |
870 | self.ui.debug(" ancestor %s local %s remote %s\n" % |
|
855 | self.ui.debug(" ancestor %s local %s remote %s\n" % | |
871 | (short(man), short(m1n), short(m2n))) |
|
856 | (short(man), short(m1n), short(m2n))) | |
872 |
|
857 | |||
@@ -876,16 +861,20 b' class localrepository:' | |||||
876 |
|
861 | |||
877 | # construct a working dir manifest |
|
862 | # construct a working dir manifest | |
878 | mw = m1.copy() |
|
863 | mw = m1.copy() | |
879 | for f in a + c: |
|
864 | for f in a + c + u: | |
880 |
mw[f] = |
|
865 | mw[f] = "" | |
881 | for f in d: |
|
866 | for f in d: | |
882 | del mw[f] |
|
867 | if f in mw: del mw[f] | |
883 |
|
868 | |||
884 | for f, n in mw.iteritems(): |
|
869 | for f, n in mw.iteritems(): | |
885 | if f in m2: |
|
870 | if f in m2: | |
886 | if n != m2[f]: |
|
871 | if n != m2[f]: | |
887 | self.ui.debug(" %s versions differ, do resolve\n" % f) |
|
872 | a = ma.get(f, nullid) | |
888 |
|
|
873 | if n != a and m2[f] != a: | |
|
874 | self.ui.debug(" %s versions differ, do resolve\n" % f) | |||
|
875 | merge[f] = (m1.get(f, nullid), m2[f]) | |||
|
876 | else: | |||
|
877 | get[f] = m2[f] | |||
889 | del m2[f] |
|
878 | del m2[f] | |
890 | elif f in ma: |
|
879 | elif f in ma: | |
891 | if n != ma[f]: |
|
880 | if n != ma[f]: | |
@@ -896,25 +885,36 b' class localrepository:' | |||||
896 | remove.append(f) |
|
885 | remove.append(f) | |
897 | else: |
|
886 | else: | |
898 | self.ui.debug("other deleted %s\n" % f) |
|
887 | self.ui.debug("other deleted %s\n" % f) | |
899 |
|
|
888 | remove.append(f) # other deleted it | |
900 | else: |
|
889 | else: | |
901 | self.ui.debug("local created %s\n" %f) |
|
890 | if n == m1.get(f, nullid): # same as parent | |
|
891 | self.ui.debug("remote deleted %s\n" % f) | |||
|
892 | remove.append(f) | |||
|
893 | else: | |||
|
894 | self.ui.debug("working dir created %s, keeping\n" % f) | |||
902 |
|
895 | |||
903 | for f, n in m2.iteritems(): |
|
896 | for f, n in m2.iteritems(): | |
904 | if f in ma: |
|
897 | if f in ma and n != ma[f]: | |
905 | if n != ma[f]: |
|
|||
906 | r = self.ui.prompt( |
|
898 | r = self.ui.prompt( | |
907 | ("remote changed %s which local deleted\n" % f) + |
|
899 | ("remote changed %s which local deleted\n" % f) + | |
908 | "(k)eep or (d)elete?", "[kd]", "k") |
|
900 | "(k)eep or (d)elete?", "[kd]", "k") | |
909 | if r == "d": remove.append(f) |
|
901 | if r == "d": remove.append(f) | |
910 | else: |
|
|||
911 | pass # probably safe |
|
|||
912 | else: |
|
902 | else: | |
913 |
self.ui.debug("remote created %s |
|
903 | self.ui.debug("remote created %s\n" % f) | |
914 | get[f] = n |
|
904 | get[f] = n | |
915 |
|
905 | |||
916 | del mw, m1, m2, ma |
|
906 | del mw, m1, m2, ma | |
917 |
|
907 | |||
|
908 | if not merge: | |||
|
909 | # we don't need to do any magic, just jump to the new rev | |||
|
910 | mode = 'n' | |||
|
911 | p1, p2 = p2, nullid | |||
|
912 | else: | |||
|
913 | # we have to remember what files we needed to get/change | |||
|
914 | # because any file that's different from either one of its | |||
|
915 | # parents must be in the changeset | |||
|
916 | mode = 'm' | |||
|
917 | ||||
918 | self.dirstate.setparents(p1, p2) |
|
918 | self.dirstate.setparents(p1, p2) | |
919 |
|
919 | |||
920 | # get the files we don't need to change |
|
920 | # get the files we don't need to change | |
@@ -929,26 +929,24 b' class localrepository:' | |||||
929 | except IOError: |
|
929 | except IOError: | |
930 | os.makedirs(os.path.dirname(f)) |
|
930 | os.makedirs(os.path.dirname(f)) | |
931 | file(self.wjoin(f), "w").write(t) |
|
931 | file(self.wjoin(f), "w").write(t) | |
932 |
|
932 | self.dirstate.update([f], mode) | ||
933 | # we have to remember what files we needed to get/change |
|
|||
934 | # because any file that's different from either one of its |
|
|||
935 | # parents must be in the changeset |
|
|||
936 | self.dirstate.update(files, 'm') |
|
|||
937 |
|
933 | |||
938 | # merge the tricky bits |
|
934 | # merge the tricky bits | |
939 | files = merge.keys() |
|
935 | files = merge.keys() | |
940 | files.sort() |
|
936 | files.sort() | |
941 | for f in files: |
|
937 | for f in files: | |
|
938 | self.status("mering %f\n" % f) | |||
942 | m, o = merge[f] |
|
939 | m, o = merge[f] | |
943 | self.merge3(f, m, o) |
|
940 | self.merge3(f, m, o) | |
944 |
|
941 | self.dirstate.update([f], 'm') | ||
945 | # same here |
|
|||
946 | self.dirstate.update(files, 'm') |
|
|||
947 |
|
942 | |||
948 | for f in remove: |
|
943 | for f in remove: | |
949 | self.ui.note("removing %s\n" % f) |
|
944 | self.ui.note("removing %s\n" % f) | |
950 |
|
|
945 | os.unlink(f) | |
951 | self.dirstate.update(remove, 'r') |
|
946 | if mode == 'n': | |
|
947 | self.dirstate.forget(remove) | |||
|
948 | else: | |||
|
949 | self.dirstate.update(remove, 'r') | |||
952 |
|
950 | |||
953 | def merge3(self, fn, my, other): |
|
951 | def merge3(self, fn, my, other): | |
954 | """perform a 3-way merge in the working directory""" |
|
952 | """perform a 3-way merge in the working directory""" |
General Comments 0
You need to be logged in to leave comments.
Login now