##// END OF EJS Templates
git: show the version of `pygit2` with verbose version output...
Matt Harbison -
r46562:c7c1efdf default
parent child Browse files
Show More
@@ -1,340 +1,343
1 1 """grant Mercurial the ability to operate on Git repositories. (EXPERIMENTAL)
2 2
3 3 This is currently super experimental. It probably will consume your
4 4 firstborn a la Rumpelstiltskin, etc.
5 5 """
6 6
7 7 from __future__ import absolute_import
8 8
9 9 import os
10 10
11 11 from mercurial.i18n import _
12 12
13 13 from mercurial import (
14 14 commands,
15 15 error,
16 16 extensions,
17 17 localrepo,
18 18 pycompat,
19 19 registrar,
20 20 scmutil,
21 21 store,
22 22 util,
23 23 )
24 24
25 25 from . import (
26 26 dirstate,
27 27 gitlog,
28 28 gitutil,
29 29 index,
30 30 )
31 31
32 32 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
33 33 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
34 34 # be specifying the version(s) of Mercurial they are tested with, or
35 35 # leave the attribute unspecified.
36 36 testedwith = b'ships-with-hg-core'
37 37
38 38 configtable = {}
39 39 configitem = registrar.configitem(configtable)
40 40 # git.log-index-cache-miss: internal knob for testing
41 41 configitem(
42 42 b"git",
43 43 b"log-index-cache-miss",
44 44 default=False,
45 45 )
46 46
47 getversion = gitutil.pygit2_version
48
49
47 50 # TODO: extract an interface for this in core
48 51 class gitstore(object): # store.basicstore):
49 52 def __init__(self, path, vfstype):
50 53 self.vfs = vfstype(path)
51 54 self.path = self.vfs.base
52 55 self.createmode = store._calcmode(self.vfs)
53 56 # above lines should go away in favor of:
54 57 # super(gitstore, self).__init__(path, vfstype)
55 58
56 59 self.git = gitutil.get_pygit2().Repository(
57 60 os.path.normpath(os.path.join(path, b'..', b'.git'))
58 61 )
59 62 self._progress_factory = lambda *args, **kwargs: None
60 63 self._logfn = lambda x: None
61 64
62 65 @util.propertycache
63 66 def _db(self):
64 67 # We lazy-create the database because we want to thread a
65 68 # progress callback down to the indexing process if it's
66 69 # required, and we don't have a ui handle in makestore().
67 70 return index.get_index(self.git, self._logfn, self._progress_factory)
68 71
69 72 def join(self, f):
70 73 """Fake store.join method for git repositories.
71 74
72 75 For the most part, store.join is used for @storecache
73 76 decorators to invalidate caches when various files
74 77 change. We'll map the ones we care about, and ignore the rest.
75 78 """
76 79 if f in (b'00changelog.i', b'00manifest.i'):
77 80 # This is close enough: in order for the changelog cache
78 81 # to be invalidated, HEAD will have to change.
79 82 return os.path.join(self.path, b'HEAD')
80 83 elif f == b'lock':
81 84 # TODO: we probably want to map this to a git lock, I
82 85 # suspect index.lock. We should figure out what the
83 86 # most-alike file is in git-land. For now we're risking
84 87 # bad concurrency errors if another git client is used.
85 88 return os.path.join(self.path, b'hgit-bogus-lock')
86 89 elif f in (b'obsstore', b'phaseroots', b'narrowspec', b'bookmarks'):
87 90 return os.path.join(self.path, b'..', b'.hg', f)
88 91 raise NotImplementedError(b'Need to pick file for %s.' % f)
89 92
90 93 def changelog(self, trypending):
91 94 # TODO we don't have a plan for trypending in hg's git support yet
92 95 return gitlog.changelog(self.git, self._db)
93 96
94 97 def manifestlog(self, repo, storenarrowmatch):
95 98 # TODO handle storenarrowmatch and figure out if we need the repo arg
96 99 return gitlog.manifestlog(self.git, self._db)
97 100
98 101 def invalidatecaches(self):
99 102 pass
100 103
101 104 def write(self, tr=None):
102 105 # normally this handles things like fncache writes, which we don't have
103 106 pass
104 107
105 108
106 109 def _makestore(orig, requirements, storebasepath, vfstype):
107 110 if b'git' in requirements:
108 111 if not os.path.exists(os.path.join(storebasepath, b'..', b'.git')):
109 112 raise error.Abort(
110 113 _(
111 114 b'repository specified git format in '
112 115 b'.hg/requires but has no .git directory'
113 116 )
114 117 )
115 118 # Check for presence of pygit2 only here. The assumption is that we'll
116 119 # run this code iff we'll later need pygit2.
117 120 if gitutil.get_pygit2() is None:
118 121 raise error.Abort(
119 122 _(
120 123 b'the git extension requires the Python '
121 124 b'pygit2 library to be installed'
122 125 )
123 126 )
124 127
125 128 return gitstore(storebasepath, vfstype)
126 129 return orig(requirements, storebasepath, vfstype)
127 130
128 131
129 132 class gitfilestorage(object):
130 133 def file(self, path):
131 134 if path[0:1] == b'/':
132 135 path = path[1:]
133 136 return gitlog.filelog(self.store.git, self.store._db, path)
134 137
135 138
136 139 def _makefilestorage(orig, requirements, features, **kwargs):
137 140 store = kwargs['store']
138 141 if isinstance(store, gitstore):
139 142 return gitfilestorage
140 143 return orig(requirements, features, **kwargs)
141 144
142 145
143 146 def _setupdothg(ui, path):
144 147 dothg = os.path.join(path, b'.hg')
145 148 if os.path.exists(dothg):
146 149 ui.warn(_(b'git repo already initialized for hg\n'))
147 150 else:
148 151 os.mkdir(os.path.join(path, b'.hg'))
149 152 # TODO is it ok to extend .git/info/exclude like this?
150 153 with open(
151 154 os.path.join(path, b'.git', b'info', b'exclude'), 'ab'
152 155 ) as exclude:
153 156 exclude.write(b'\n.hg\n')
154 157 with open(os.path.join(dothg, b'requires'), 'wb') as f:
155 158 f.write(b'git\n')
156 159
157 160
158 161 _BMS_PREFIX = 'refs/heads/'
159 162
160 163
161 164 class gitbmstore(object):
162 165 def __init__(self, gitrepo):
163 166 self.gitrepo = gitrepo
164 167 self._aclean = True
165 168 self._active = gitrepo.references['HEAD'] # git head, not mark
166 169
167 170 def __contains__(self, name):
168 171 return (
169 172 _BMS_PREFIX + pycompat.fsdecode(name)
170 173 ) in self.gitrepo.references
171 174
172 175 def __iter__(self):
173 176 for r in self.gitrepo.listall_references():
174 177 if r.startswith(_BMS_PREFIX):
175 178 yield pycompat.fsencode(r[len(_BMS_PREFIX) :])
176 179
177 180 def __getitem__(self, k):
178 181 return (
179 182 self.gitrepo.references[_BMS_PREFIX + pycompat.fsdecode(k)]
180 183 .peel()
181 184 .id.raw
182 185 )
183 186
184 187 def get(self, k, default=None):
185 188 try:
186 189 if k in self:
187 190 return self[k]
188 191 return default
189 192 except gitutil.get_pygit2().InvalidSpecError:
190 193 return default
191 194
192 195 @property
193 196 def active(self):
194 197 h = self.gitrepo.references['HEAD']
195 198 if not isinstance(h.target, str) or not h.target.startswith(
196 199 _BMS_PREFIX
197 200 ):
198 201 return None
199 202 return pycompat.fsencode(h.target[len(_BMS_PREFIX) :])
200 203
201 204 @active.setter
202 205 def active(self, mark):
203 206 githead = mark is not None and (_BMS_PREFIX + mark) or None
204 207 if githead is not None and githead not in self.gitrepo.references:
205 208 raise AssertionError(b'bookmark %s does not exist!' % mark)
206 209
207 210 self._active = githead
208 211 self._aclean = False
209 212
210 213 def _writeactive(self):
211 214 if self._aclean:
212 215 return
213 216 self.gitrepo.references.create('HEAD', self._active, True)
214 217 self._aclean = True
215 218
216 219 def names(self, node):
217 220 r = []
218 221 for ref in self.gitrepo.listall_references():
219 222 if not ref.startswith(_BMS_PREFIX):
220 223 continue
221 224 if self.gitrepo.references[ref].peel().id.raw != node:
222 225 continue
223 226 r.append(pycompat.fsencode(ref[len(_BMS_PREFIX) :]))
224 227 return r
225 228
226 229 # Cleanup opportunity: this is *identical* to core's bookmarks store.
227 230 def expandname(self, bname):
228 231 if bname == b'.':
229 232 if self.active:
230 233 return self.active
231 234 raise error.RepoLookupError(_(b"no active bookmark"))
232 235 return bname
233 236
234 237 def applychanges(self, repo, tr, changes):
235 238 """Apply a list of changes to bookmarks"""
236 239 # TODO: this should respect transactions, but that's going to
237 240 # require enlarging the gitbmstore to know how to do in-memory
238 241 # temporary writes and read those back prior to transaction
239 242 # finalization.
240 243 for name, node in changes:
241 244 if node is None:
242 245 self.gitrepo.references.delete(
243 246 _BMS_PREFIX + pycompat.fsdecode(name)
244 247 )
245 248 else:
246 249 self.gitrepo.references.create(
247 250 _BMS_PREFIX + pycompat.fsdecode(name),
248 251 gitutil.togitnode(node),
249 252 force=True,
250 253 )
251 254
252 255 def checkconflict(self, mark, force=False, target=None):
253 256 githead = _BMS_PREFIX + mark
254 257 cur = self.gitrepo.references['HEAD']
255 258 if githead in self.gitrepo.references and not force:
256 259 if target:
257 260 if self.gitrepo.references[githead] == target and target == cur:
258 261 # re-activating a bookmark
259 262 return []
260 263 # moving a bookmark - forward?
261 264 raise NotImplementedError
262 265 raise error.Abort(
263 266 _(b"bookmark '%s' already exists (use -f to force)") % mark
264 267 )
265 268 if len(mark) > 3 and not force:
266 269 try:
267 270 shadowhash = scmutil.isrevsymbol(self._repo, mark)
268 271 except error.LookupError: # ambiguous identifier
269 272 shadowhash = False
270 273 if shadowhash:
271 274 self._repo.ui.warn(
272 275 _(
273 276 b"bookmark %s matches a changeset hash\n"
274 277 b"(did you leave a -r out of an 'hg bookmark' "
275 278 b"command?)\n"
276 279 )
277 280 % mark
278 281 )
279 282 return []
280 283
281 284
282 285 def init(orig, ui, dest=b'.', **opts):
283 286 if opts.get('git', False):
284 287 path = os.path.abspath(dest)
285 288 # TODO: walk up looking for the git repo
286 289 _setupdothg(ui, path)
287 290 return 0
288 291 return orig(ui, dest=dest, **opts)
289 292
290 293
291 294 def reposetup(ui, repo):
292 295 if repo.local() and isinstance(repo.store, gitstore):
293 296 orig = repo.__class__
294 297 repo.store._progress_factory = repo.ui.makeprogress
295 298 if ui.configbool(b'git', b'log-index-cache-miss'):
296 299 repo.store._logfn = repo.ui.warn
297 300
298 301 class gitlocalrepo(orig):
299 302 def _makedirstate(self):
300 303 # TODO narrow support here
301 304 return dirstate.gitdirstate(
302 305 self.ui, self.vfs.base, self.store.git
303 306 )
304 307
305 308 def commit(self, *args, **kwargs):
306 309 ret = orig.commit(self, *args, **kwargs)
307 310 if ret is None:
308 311 # there was nothing to commit, so we should skip
309 312 # the index fixup logic we'd otherwise do.
310 313 return None
311 314 tid = self.store.git[gitutil.togitnode(ret)].tree.id
312 315 # DANGER! This will flush any writes staged to the
313 316 # index in Git, but we're sidestepping the index in a
314 317 # way that confuses git when we commit. Alas.
315 318 self.store.git.index.read_tree(tid)
316 319 self.store.git.index.write()
317 320 return ret
318 321
319 322 @property
320 323 def _bookmarks(self):
321 324 return gitbmstore(self.store.git)
322 325
323 326 repo.__class__ = gitlocalrepo
324 327 return repo
325 328
326 329
327 330 def _featuresetup(ui, supported):
328 331 # don't die on seeing a repo with the git requirement
329 332 supported |= {b'git'}
330 333
331 334
332 335 def extsetup(ui):
333 336 extensions.wrapfunction(localrepo, b'makestore', _makestore)
334 337 extensions.wrapfunction(localrepo, b'makefilestorage', _makefilestorage)
335 338 # Inject --git flag for `hg init`
336 339 entry = extensions.wrapcommand(commands.table, b'init', init)
337 340 entry[1].extend(
338 341 [(b'', b'git', None, b'setup up a git repository instead of hg')]
339 342 )
340 343 localrepo.featuresetupfuncs.add(_featuresetup)
@@ -1,40 +1,53
1 1 """utilities to assist in working with pygit2"""
2 2 from __future__ import absolute_import
3 3
4 4 from mercurial.node import bin, hex, nullid
5 5
6 6 from mercurial import pycompat
7 7
8 8 pygit2_module = None
9 9
10 10
11 11 def get_pygit2():
12 12 global pygit2_module
13 13 if pygit2_module is None:
14 14 try:
15 15 import pygit2 as pygit2_module
16 16
17 17 pygit2_module.InvalidSpecError
18 18 except (ImportError, AttributeError):
19 19 pass
20 20 return pygit2_module
21 21
22 22
23 def pygit2_version():
24 mod = get_pygit2()
25 v = "N/A"
26
27 if mod:
28 try:
29 v = mod.__version__
30 except AttributeError:
31 pass
32
33 return b"(pygit2 %s)" % v.encode("utf-8")
34
35
23 36 def togitnode(n):
24 37 """Wrapper to convert a Mercurial binary node to a unicode hexlified node.
25 38
26 39 pygit2 and sqlite both need nodes as strings, not bytes.
27 40 """
28 41 assert len(n) == 20
29 42 return pycompat.sysstr(hex(n))
30 43
31 44
32 45 def fromgitnode(n):
33 46 """Opposite of togitnode."""
34 47 assert len(n) == 40
35 48 if pycompat.ispy3:
36 49 return bin(n.encode('ascii'))
37 50 return bin(n)
38 51
39 52
40 53 nullgit = togitnode(nullid)
@@ -1,354 +1,358
1 1 #require pygit2
2 2
3 3 Setup:
4 4 $ GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
5 5 > GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
6 6 > GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0000"; export GIT_AUTHOR_DATE
7 7 > GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME
8 8 > GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL
9 9 > GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE
10 10 > count=10
11 11 > gitcommit() {
12 12 > GIT_AUTHOR_DATE="2007-01-01 00:00:$count +0000";
13 13 > GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
14 14 > git commit "$@" >/dev/null 2>/dev/null || echo "git commit error"
15 15 > count=`expr $count + 1`
16 16 > }
17 17
18 18
19 $ hg version -v --config extensions.git= | grep '^[E ]'
20 Enabled extensions:
21 git internal (pygit2 *) (glob)
22
19 23 Test auto-loading extension works:
20 24 $ mkdir nogit
21 25 $ cd nogit
22 26 $ mkdir .hg
23 27 $ echo git >> .hg/requires
24 28 $ hg status
25 29 abort: repository specified git format in .hg/requires but has no .git directory
26 30 [255]
27 31 $ git init
28 32 Initialized empty Git repository in $TESTTMP/nogit/.git/
29 33 This status invocation shows some hg gunk because we didn't use
30 34 `hg init --git`, which fixes up .git/info/exclude for us.
31 35 $ hg status
32 36 ? .hg/cache/git-commits.sqlite
33 37 ? .hg/cache/git-commits.sqlite-shm
34 38 ? .hg/cache/git-commits.sqlite-wal
35 39 ? .hg/requires
36 40 $ cd ..
37 41
38 42 Now globally enable extension for the rest of the test:
39 43 $ cat <<EOF >> $HGRCPATH
40 44 > [extensions]
41 45 > git=
42 46 > [git]
43 47 > log-index-cache-miss = yes
44 48 > EOF
45 49
46 50 Make a new repo with git:
47 51 $ mkdir foo
48 52 $ cd foo
49 53 $ git init
50 54 Initialized empty Git repository in $TESTTMP/foo/.git/
51 55 Ignore the .hg directory within git:
52 56 $ echo .hg >> .git/info/exclude
53 57 $ echo alpha > alpha
54 58 $ git add alpha
55 59 $ gitcommit -am 'Add alpha'
56 60 $ echo beta > beta
57 61 $ git add beta
58 62 $ gitcommit -am 'Add beta'
59 63 $ echo gamma > gamma
60 64 $ git status
61 65 On branch master
62 66 Untracked files:
63 67 (use "git add <file>..." to include in what will be committed)
64 68 gamma
65 69
66 70 nothing added to commit but untracked files present (use "git add" to track)
67 71
68 72 Without creating the .hg, hg status fails:
69 73 $ hg status
70 74 abort: no repository found in '$TESTTMP/foo' (.hg not found)
71 75 [10]
72 76 But if you run hg init --git, it works:
73 77 $ hg init --git
74 78 $ hg id --traceback
75 79 heads mismatch, rebuilding dagcache
76 80 3d9be8deba43 tip master
77 81 $ hg status
78 82 ? gamma
79 83 Log works too:
80 84 $ hg log
81 85 changeset: 1:3d9be8deba43
82 86 bookmark: master
83 87 tag: tip
84 88 user: test <test@example.org>
85 89 date: Mon Jan 01 00:00:11 2007 +0000
86 90 summary: Add beta
87 91
88 92 changeset: 0:c5864c9d16fb
89 93 user: test <test@example.org>
90 94 date: Mon Jan 01 00:00:10 2007 +0000
91 95 summary: Add alpha
92 96
93 97
94 98
95 99 and bookmarks:
96 100 $ hg bookmarks
97 101 * master 1:3d9be8deba43
98 102
99 103 diff even works transparently in both systems:
100 104 $ echo blah >> alpha
101 105 $ git diff
102 106 diff --git a/alpha b/alpha
103 107 index 4a58007..faed1b7 100644
104 108 --- a/alpha
105 109 +++ b/alpha
106 110 @@ -1* +1,2 @@ (glob)
107 111 alpha
108 112 +blah
109 113 $ hg diff --git
110 114 diff --git a/alpha b/alpha
111 115 --- a/alpha
112 116 +++ b/alpha
113 117 @@ -1,1 +1,2 @@
114 118 alpha
115 119 +blah
116 120
117 121 Remove a file, it shows as such:
118 122 $ rm alpha
119 123 $ hg status
120 124 ! alpha
121 125 ? gamma
122 126
123 127 Revert works:
124 128 $ hg revert alpha --traceback
125 129 $ hg status
126 130 ? gamma
127 131 $ git status
128 132 On branch master
129 133 Untracked files:
130 134 (use "git add <file>..." to include in what will be committed)
131 135 gamma
132 136
133 137 nothing added to commit but untracked files present (use "git add" to track)
134 138
135 139 Add shows sanely in both:
136 140 $ hg add gamma
137 141 $ hg status
138 142 A gamma
139 143 $ hg files
140 144 alpha
141 145 beta
142 146 gamma
143 147 $ git ls-files
144 148 alpha
145 149 beta
146 150 gamma
147 151 $ git status
148 152 On branch master
149 153 Changes to be committed:
150 154 (use "git restore --staged <file>..." to unstage)
151 155 new file: gamma
152 156
153 157
154 158 forget does what it should as well:
155 159 $ hg forget gamma
156 160 $ hg status
157 161 ? gamma
158 162 $ git status
159 163 On branch master
160 164 Untracked files:
161 165 (use "git add <file>..." to include in what will be committed)
162 166 gamma
163 167
164 168 nothing added to commit but untracked files present (use "git add" to track)
165 169
166 170 clean up untracked file
167 171 $ rm gamma
168 172
169 173 hg log FILE
170 174
171 175 $ echo a >> alpha
172 176 $ hg ci -m 'more alpha' --traceback --date '1583522787 18000'
173 177 $ echo b >> beta
174 178 $ hg ci -m 'more beta'
175 179 heads mismatch, rebuilding dagcache
176 180 $ echo a >> alpha
177 181 $ hg ci -m 'even more alpha'
178 182 heads mismatch, rebuilding dagcache
179 183 $ hg log -G alpha
180 184 heads mismatch, rebuilding dagcache
181 185 @ changeset: 4:6626247b7dc8
182 186 : bookmark: master
183 187 : tag: tip
184 188 : user: test <test>
185 189 : date: Thu Jan 01 00:00:00 1970 +0000
186 190 : summary: even more alpha
187 191 :
188 192 o changeset: 2:a1983dd7fb19
189 193 : user: test <test>
190 194 : date: Fri Mar 06 14:26:27 2020 -0500
191 195 : summary: more alpha
192 196 :
193 197 o changeset: 0:c5864c9d16fb
194 198 user: test <test@example.org>
195 199 date: Mon Jan 01 00:00:10 2007 +0000
196 200 summary: Add alpha
197 201
198 202 $ hg log -G beta
199 203 o changeset: 3:d8ee22687733
200 204 : user: test <test>
201 205 : date: Thu Jan 01 00:00:00 1970 +0000
202 206 : summary: more beta
203 207 :
204 208 o changeset: 1:3d9be8deba43
205 209 | user: test <test@example.org>
206 210 ~ date: Mon Jan 01 00:00:11 2007 +0000
207 211 summary: Add beta
208 212
209 213
210 214 $ hg log -r "children(3d9be8deba43)" -T"{node|short} {children}\n"
211 215 a1983dd7fb19 3:d8ee22687733
212 216
213 217 hg annotate
214 218
215 219 $ hg annotate alpha
216 220 0: alpha
217 221 2: a
218 222 4: a
219 223 $ hg annotate beta
220 224 1: beta
221 225 3: b
222 226
223 227
224 228 Files in subdirectories. TODO: case-folding support, make this `A`
225 229 instead of `a`.
226 230
227 231 $ mkdir a
228 232 $ echo "This is file mu." > a/mu
229 233 $ hg ci -A -m 'Introduce file a/mu'
230 234 adding a/mu
231 235
232 236 Both hg and git agree a/mu is part of the repo
233 237
234 238 $ git ls-files
235 239 a/mu
236 240 alpha
237 241 beta
238 242 $ hg files
239 243 a/mu
240 244 alpha
241 245 beta
242 246
243 247 hg and git status both clean
244 248
245 249 $ git status
246 250 On branch master
247 251 nothing to commit, working tree clean
248 252 $ hg status
249 253 heads mismatch, rebuilding dagcache
250 254
251 255
252 256 node|shortest works correctly
253 257 $ hg log -T '{node}\n' | sort
254 258 3d9be8deba43482be2c81a4cb4be1f10d85fa8bc
255 259 6626247b7dc8f231b183b8a4761c89139baca2ad
256 260 a1983dd7fb19cbd83ad5a1c2fc8bf3d775dea12f
257 261 ae1ab744f95bfd5b07cf573baef98a778058537b
258 262 c5864c9d16fb3431fe2c175ff84dc6accdbb2c18
259 263 d8ee22687733a1991813560b15128cd9734f4b48
260 264 $ hg log -r ae1ab744f95bfd5b07cf573baef98a778058537b --template "{shortest(node,1)}\n"
261 265 ae
262 266
263 267 This coveres changelog.findmissing()
264 268 $ hg merge --preview 3d9be8deba43
265 269
266 270 This covers manifest.diff()
267 271 $ hg diff -c 3d9be8deba43
268 272 diff -r c5864c9d16fb -r 3d9be8deba43 beta
269 273 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
270 274 +++ b/beta Mon Jan 01 00:00:11 2007 +0000
271 275 @@ -0,0 +1,1 @@
272 276 +beta
273 277
274 278
275 279 Interactive commit should work as expected
276 280
277 281 $ echo bar >> alpha
278 282 $ echo bar >> beta
279 283 $ hg commit -m "test interactive commit" -i --config ui.interactive=true --config ui.interface=text << EOF
280 284 > y
281 285 > y
282 286 > n
283 287 > EOF
284 288 diff --git a/alpha b/alpha
285 289 1 hunks, 1 lines changed
286 290 examine changes to 'alpha'?
287 291 (enter ? for help) [Ynesfdaq?] y
288 292
289 293 @@ -1,3 +1,4 @@
290 294 alpha
291 295 a
292 296 a
293 297 +bar
294 298 record change 1/2 to 'alpha'?
295 299 (enter ? for help) [Ynesfdaq?] y
296 300
297 301 diff --git a/beta b/beta
298 302 1 hunks, 1 lines changed
299 303 examine changes to 'beta'?
300 304 (enter ? for help) [Ynesfdaq?] n
301 305
302 306 Status should be consistent for both systems
303 307
304 308 $ hg status
305 309 heads mismatch, rebuilding dagcache
306 310 M beta
307 311 $ git status | egrep -v '^$|^ \(use '
308 312 On branch master
309 313 Changes not staged for commit:
310 314 modified: beta
311 315 no changes added to commit (use "git add" and/or "git commit -a")
312 316
313 317 Contents of each commit should be the same
314 318
315 319 $ hg ex -r .
316 320 # HG changeset patch
317 321 # User test <test>
318 322 # Date 0 0
319 323 # Thu Jan 01 00:00:00 1970 +0000
320 324 # Node ID 80adc61cf57e99f6a412d83fee6239d1556cefcf
321 325 # Parent ae1ab744f95bfd5b07cf573baef98a778058537b
322 326 test interactive commit
323 327
324 328 diff -r ae1ab744f95b -r 80adc61cf57e alpha
325 329 --- a/alpha Thu Jan 01 00:00:00 1970 +0000
326 330 +++ b/alpha Thu Jan 01 00:00:00 1970 +0000
327 331 @@ -1,3 +1,4 @@
328 332 alpha
329 333 a
330 334 a
331 335 +bar
332 336 $ git show
333 337 commit 80adc61cf57e99f6a412d83fee6239d1556cefcf
334 338 Author: test <test>
335 339 Date: Thu Jan 1 00:00:00 1970 +0000
336 340
337 341 test interactive commit
338 342
339 343 diff --git a/alpha b/alpha
340 344 index d112a75..d2a2e9a 100644
341 345 --- a/alpha
342 346 +++ b/alpha
343 347 @@ -1,3 +1,4 @@
344 348 alpha
345 349 a
346 350 a
347 351 +bar
348 352
349 353 Deleting files should also work (this was issue6398)
350 354 $ hg revert -r . --all
351 355 reverting beta
352 356 $ hg rm beta
353 357 $ hg ci -m 'remove beta'
354 358
General Comments 0
You need to be logged in to leave comments. Login now