61 # Journal recording, register hooks and storage object |
60 # Journal recording, register hooks and storage object |
62 def extsetup(ui): |
61 def extsetup(ui): |
63 extensions.wrapfunction(dispatch, 'runcommand', runcommand) |
62 extensions.wrapfunction(dispatch, 'runcommand', runcommand) |
64 extensions.wrapfunction(bookmarks.bmstore, '_write', recordbookmarks) |
63 extensions.wrapfunction(bookmarks.bmstore, '_write', recordbookmarks) |
65 extensions.wrapfunction( |
64 extensions.wrapfunction( |
66 dirstate.dirstate, '_writedirstate', recorddirstateparents) |
|
67 extensions.wrapfunction( |
|
68 localrepo.localrepository.dirstate, 'func', wrapdirstate) |
65 localrepo.localrepository.dirstate, 'func', wrapdirstate) |
69 extensions.wrapfunction(hg, 'postshare', wrappostshare) |
66 extensions.wrapfunction(hg, 'postshare', wrappostshare) |
70 extensions.wrapfunction(hg, 'copystore', unsharejournal) |
67 extensions.wrapfunction(hg, 'copystore', unsharejournal) |
71 |
68 |
72 def reposetup(ui, repo): |
69 def reposetup(ui, repo): |
82 def wrapdirstate(orig, repo): |
79 def wrapdirstate(orig, repo): |
83 """Make journal storage available to the dirstate object""" |
80 """Make journal storage available to the dirstate object""" |
84 dirstate = orig(repo) |
81 dirstate = orig(repo) |
85 if util.safehasattr(repo, 'journal'): |
82 if util.safehasattr(repo, 'journal'): |
86 dirstate.journalstorage = repo.journal |
83 dirstate.journalstorage = repo.journal |
|
84 dirstate.addparentchangecallback('journal', recorddirstateparents) |
87 return dirstate |
85 return dirstate |
88 |
86 |
89 def recorddirstateparents(orig, dirstate, dirstatefp): |
87 def recorddirstateparents(dirstate, old, new): |
90 """Records all dirstate parent changes in the journal.""" |
88 """Records all dirstate parent changes in the journal.""" |
|
89 old = list(old) |
|
90 new = list(new) |
91 if util.safehasattr(dirstate, 'journalstorage'): |
91 if util.safehasattr(dirstate, 'journalstorage'): |
92 old = [node.nullid, node.nullid] |
92 # only record two hashes if there was a merge |
93 nodesize = len(node.nullid) |
93 oldhashes = old[:1] if old[1] == node.nullid else old |
94 try: |
94 newhashes = new[:1] if new[1] == node.nullid else new |
95 # The only source for the old state is in the dirstate file still |
95 dirstate.journalstorage.record( |
96 # on disk; the in-memory dirstate object only contains the new |
96 wdirparenttype, '.', oldhashes, newhashes) |
97 # state. dirstate._opendirstatefile() switches beteen .hg/dirstate |
|
98 # and .hg/dirstate.pending depending on the transaction state. |
|
99 with dirstate._opendirstatefile() as fp: |
|
100 state = fp.read(2 * nodesize) |
|
101 if len(state) == 2 * nodesize: |
|
102 old = [state[:nodesize], state[nodesize:]] |
|
103 except IOError: |
|
104 pass |
|
105 |
|
106 new = dirstate.parents() |
|
107 if old != new: |
|
108 # only record two hashes if there was a merge |
|
109 oldhashes = old[:1] if old[1] == node.nullid else old |
|
110 newhashes = new[:1] if new[1] == node.nullid else new |
|
111 dirstate.journalstorage.record( |
|
112 wdirparenttype, '.', oldhashes, newhashes) |
|
113 |
|
114 return orig(dirstate, dirstatefp) |
|
115 |
97 |
116 # hooks to record bookmark changes (both local and remote) |
98 # hooks to record bookmark changes (both local and remote) |
117 def recordbookmarks(orig, store, fp): |
99 def recordbookmarks(orig, store, fp): |
118 """Records all bookmark changes in the journal.""" |
100 """Records all bookmark changes in the journal.""" |
119 repo = store._repo |
101 repo = store._repo |