fce44ae9 Andy McCall 1 month ago ↶
1
2
2863456a Andy McCall 1 month ago ↶
3
use super :: format:: { deps_line, deps_of, plural, short_id, short_meta_id, signature_line, when} ;
fce44ae9 Andy McCall 1 month ago ↶
4
use super :: open;
135212de Andy McCall 1 month ago ↶
5
use super :: ui;
fce44ae9 Andy McCall 1 month ago ↶
6
use anyhow:: Result;
7
use oxy_core:: repo:: { render_change, ChangeStatus, Repo} ;
8
use std:: path:: PathBuf;
9
10
pub fn init ( path : Option< PathBuf> ) -> Result< i32 > {
11
let path = path.unwrap_or ( std:: env:: current_dir( ) ? ) ;
12
let repo = Repo:: init( & path) ? ;
135212de Andy McCall 1 month ago ↶
13
println! ( " {} oxy repository in {} " , ui:: ok( " Initialized" ) , ui:: path( repo.root ( ) .display ( ) ) ) ;
14
println! ( " bookmark {} author {} <{} >" , ui:: id( & repo.config.bookmark) , repo.config.author_name, repo.config.author_email) ;
fce44ae9 Andy McCall 1 month ago ↶
15
Ok ( 0 )
16
}
17
18
fn status_tag ( s : ChangeStatus) -> & 'static str {
19
match s {
20
ChangeStatus:: Added => " A" ,
21
ChangeStatus:: Modified => " M" ,
22
ChangeStatus:: Removed => " D" ,
23
ChangeStatus:: ModeChanged => " X" ,
24
ChangeStatus:: ConflictEdited => " C!" ,
25
ChangeStatus:: Resolved => " R" ,
26
}
27
}
28
29
pub fn status ( ) -> Result< i32 > {
30
let repo = open ( ) ? ;
135212de Andy McCall 1 month ago ↶
31
let sp = ui:: spinner( " Snapshotting the working copy…" ) ;
fce44ae9 Andy McCall 1 month ago ↶
32
let snap = repo.snapshot ( " oxy status" ) ? ;
33
let heads = repo.bookmark_heads ( ) ? ;
135212de Andy McCall 1 month ago ↶
34
sp.clear ( ) ;
35
println! (
36
" {} {} on {} {} " ,
37
ui:: heading( " Working copy" ) ,
38
ui:: id( snap.wc.change_id.short ( 8 ) ) ,
39
ui:: id( & repo.config.bookmark) ,
40
ui:: dim( format! ( " ({} )" , plural ( heads.len ( ) , " head" ) ) )
41
) ;
fce44ae9 Andy McCall 1 month ago ↶
42
if snap.statuses.is_empty ( ) {
135212de Andy McCall 1 month ago ↶
43
println! ( " {} " , ui:: dim( " clean" ) ) ;
fce44ae9 Andy McCall 1 month ago ↶
44
}
45
for s in & snap.statuses {
135212de Andy McCall 1 month ago ↶
46
println! ( " {:2} {} " , ui:: tag( status_tag ( s.status) ) , ui:: path( & s.path) ) ;
fce44ae9 Andy McCall 1 month ago ↶
47
}
48
if ! snap.base_snapshot.is_conflicted ( ) {
49
return Ok ( 0 ) ;
50
}
135212de Andy McCall 1 month ago ↶
51
println! ( ) ;
52
println! ( " {} {} " , ui:: err( " Conflicts" ) , ui:: dim( " edit the marked files, or the .oxy-conflict-N candidates, then commit" ) ) ;
fce44ae9 Andy McCall 1 month ago ↶
53
for c in & snap.base_snapshot.tree.conflicts {
54
println! ( " tree: {c:?} " ) ;
55
}
56
for ( p, f) in & snap.base_snapshot.files {
57
if f.is_conflicted ( ) {
58
let state = match snap.statuses.iter ( ) .find ( | s | s.path = = * p ) .map ( | s | s.status ) {
135212de Andy McCall 1 month ago ↶
59
Some ( ChangeStatus:: Resolved) => ui:: ok( " resolved in working copy" ) ,
60
Some ( ChangeStatus:: ConflictEdited) => ui:: warn( " markers remain" ) ,
61
_ => ui:: err( " unresolved" ) ,
fce44ae9 Andy McCall 1 month ago ↶
62
} ;
135212de Andy McCall 1 month ago ↶
63
println! ( " {} {state} " , ui:: path( p) ) ;
fce44ae9 Andy McCall 1 month ago ↶
64
}
65
}
66
Ok ( 2 )
67
}
68
69
pub fn commit ( message : & str , depends_on : & [String]) -> Result< i32 > {
70
let repo = open ( ) ? ;
71
let mut deps = Vec :: new( ) ;
72
for d in depends_on {
73
deps.push ( repo.resolve_change ( d) ? ) ;
74
}
135212de Andy McCall 1 month ago ↶
75
let sp = ui:: spinner( " Committing…" ) ;
fce44ae9 Andy McCall 1 month ago ↶
76
let h = repo.commit ( message, & deps) ? ;
77
let c = repo.store ( ) .get_change ( & h) ? ;
135212de Andy McCall 1 month ago ↶
78
sp.done ( & format! ( " {} {} {} {} " , ui:: ok( " Committed" ) , ui:: id( short_id ( & c) ) , ui:: hash( format! ( " #{} " , h.short ( 12 ) ) ) , message.lines ( ) .next ( ) .unwrap_or ( " " ) ) ) ;
fce44ae9 Andy McCall 1 month ago ↶
79
Ok ( 0 )
80
}
81
82
pub fn log ( ) -> Result< i32 > {
83
let repo = open ( ) ? ;
84
repo.snapshot ( " oxy log" ) ? ;
85
for e in repo.log ( ) ? {
86
let c = & e.change;
87
let mut flags = Vec :: new( ) ;
88
if e.is_working_copy {
89
flags.push ( " working copy" ) ;
90
}
91
if e.is_head {
92
flags.push ( " head" ) ;
93
}
135212de Andy McCall 1 month ago ↶
94
let flags = if flags.is_empty ( ) { String :: new( ) } else { ui:: warn( format! ( " ({} )" , flags.join ( " , " ) ) ) } ;
2863456a Andy McCall 1 month ago ↶
95
println! ( " {} {} {} " , ui:: id( short_meta_id ( c) ) , ui:: hash( format! ( " #{} " , e.hash.short ( 12 ) ) ) , flags) ;
135212de Andy McCall 1 month ago ↶
96
println! ( " {} " , ui:: dim( when ( c.hlc.wall_ms) ) ) ;
fce44ae9 Andy McCall 1 month ago ↶
97
if ! c.deps.is_empty ( ) {
2863456a Andy McCall 1 month ago ↶
98
println! ( " {} " , ui:: dim( format! ( " deps: {} " , deps_of ( & c.deps) ) ) ) ;
fce44ae9 Andy McCall 1 month ago ↶
99
}
100
let msg = if c.message.is_empty ( ) { " (no description)" } else { & c.message } ;
101
for line in msg.lines ( ) {
102
println! ( " {line} " ) ;
103
}
104
println! ( ) ;
105
}
106
Ok ( 0 )
107
}
108
109
pub fn diff ( ) -> Result< i32 > {
110
let repo = open ( ) ? ;
111
let snap = repo.snapshot ( " oxy diff" ) ? ;
112
print! ( " {} " , render_change ( & snap.wc, & snap.base, & snap.base_snapshot) ) ;
113
Ok ( 0 )
114
}
115
116
pub fn show ( change : & str ) -> Result< i32 > {
117
let repo = open ( ) ? ;
118
repo.snapshot ( " oxy show" ) ? ;
119
let h = repo.resolve_change ( change) ? ;
120
let c = repo.store ( ) .get_change ( & h) ? ;
135212de Andy McCall 1 month ago ↶
121
println! ( " {} {} {} " , ui:: heading( " change" ) , ui:: id( short_id ( & c) ) , ui:: hash( format! ( " #{h} " ) ) ) ;
122
println! ( " kind {:?} " , c.kind) ;
123
println! ( " date {} " , when ( c.hlc.wall_ms) ) ;
124
println! ( " deps {} " , ui:: dim( deps_line ( & c) ) ) ;
125
println! ( " sig {} " , signature_line ( & repo, & h) ? ) ;
fce44ae9 Andy McCall 1 month ago ↶
126
println! ( " \n {} \n " , if c.message.is_empty ( ) { " (no description)" } else { & c.message } ) ;
127
print! ( " {} " , repo.describe_change ( & h) ? ) ;
128
Ok ( 0 )
129
}
130
131
pub fn checkout ( changes : & [String], discard : bool ) -> Result< i32 > {
132
let repo = open ( ) ? ;
133
let heads = if changes.is_empty ( ) {
134
repo.bookmark_heads ( ) ?
135
} else {
132b884b Andy McCall 1 month ago ↶
136
let mut heads = Vec :: new( ) ;
137
for c in changes {
138
heads.extend ( repo.resolve_heads ( c) ? ) ;
139
}
140
heads
fce44ae9 Andy McCall 1 month ago ↶
141
} ;
142
let spec = if changes.is_empty ( ) { repo.config.bookmark.clone ( ) } else { changes.join ( " " ) } ;
135212de Andy McCall 1 month ago ↶
143
let sp = ui:: spinner( & format! ( " Checking out {spec} …" ) ) ;
fce44ae9 Andy McCall 1 month ago ↶
144
let r = repo.checkout ( & heads, discard, & format! ( " oxy checkout {spec} " ) ) ? ;
135212de Andy McCall 1 month ago ↶
145
sp.done ( & format! ( " {} on {} : {} written, {} removed" , ui:: ok( " Working copy" ) , ui:: id( & spec) , plural ( r.written, " file" ) , r.removed) ) ;
fce44ae9 Andy McCall 1 month ago ↶
146
if r.conflicted {
135212de Andy McCall 1 month ago ↶
147
println! ( " {} " , ui:: warn( " this state has conflicts; see oxy status" ) ) ;
fce44ae9 Andy McCall 1 month ago ↶
148
}
149
Ok ( 0 )
150
}
151
152
pub fn resolve ( ) -> Result< i32 > {
153
let repo = open ( ) ? ;
154
let snap = repo.snapshot ( " oxy resolve" ) ? ;
155
if ! snap.base_snapshot.is_conflicted ( ) {
156
println! ( " The working copy's base has no conflicts." ) ;
157
return Ok ( 0 ) ;
158
}
159
let mut remaining = 0 ;
160
for ( p, f) in & snap.base_snapshot.files {
161
if ! f.is_conflicted ( ) {
162
continue ;
163
}
164
match snap.statuses.iter ( ) .find ( | s | s.path = = * p ) .map ( | s | s.status ) {
165
Some ( ChangeStatus:: Resolved) => println! ( " resolved {p} " ) ,
166
Some ( ChangeStatus:: ConflictEdited) => {
167
remaining + = 1 ;
168
println! ( " markers {p} " ) ;
169
}
170
_ => {
171
remaining + = 1 ;
172
println! ( " unresolved {p} " ) ;
173
}
174
}
175
}
176
for c in & snap.base_snapshot.tree.conflicts {
177
remaining + = 1 ;
178
println! ( " tree {c:?} " ) ;
179
}
180
if remaining = = 0 {
181
println! ( " All conflicts are resolved; `oxy commit` will record the resolution." ) ;
182
Ok ( 0 )
183
} else {
184
Ok ( 2 )
185
}
186
}
187
188
pub fn undo ( ) -> Result< i32 > {
189
let repo = open ( ) ? ;
190
let op = repo.undo ( ) ? ;
135212de Andy McCall 1 month ago ↶
191
println! ( " {} now at: {} " , ui:: ok( " Undone;" ) , ui:: dim( & op.command) ) ;
fce44ae9 Andy McCall 1 month ago ↶
192
Ok ( 0 )
193
}
194
195
pub fn op_log ( ) -> Result< i32 > {
196
let repo = open ( ) ? ;
197
for ( i, ( r, op) ) in repo.op_log ( ) ? .into_iter ( ) .enumerate ( ) {
135212de Andy McCall 1 month ago ↶
198
println! ( " {} {} {} {} " , if i = = 0 { ui:: ok( " @ " ) } else { " " .into ( ) } , ui:: hash( r.short ( 12 ) ) , ui:: dim( when ( op.hlc.wall_ms) ) , op.command) ;
fce44ae9 Andy McCall 1 month ago ↶
199
}
200
Ok ( 0 )
201
}
d02e545d Andy McCall 1 month ago ↶
202
ba160f60 Andy McCall 1 month ago ↶
203
pub fn gc ( now : bool ) -> Result< i32 > {
d02e545d Andy McCall 1 month ago ↶
204
let repo = open ( ) ? ;
135212de Andy McCall 1 month ago ↶
205
let sp = ui:: spinner( " Packing and pruning…" ) ;
ba160f60 Andy McCall 1 month ago ↶
206
let r = repo.gc ( now) ? ;
135212de Andy McCall 1 month ago ↶
207
sp.clear ( ) ;
ba160f60 Andy McCall 1 month ago ↶
208
if r.packed.objects > 0 {
d02e545d Andy McCall 1 month ago ↶
209
println! (
ba160f60 Andy McCall 1 month ago ↶
210
" Packed {} : {} bytes -> {} bytes ({:.0} %)." ,
211
plural ( r.packed.objects, " loose object" ) ,
212
r.packed.raw_bytes,
213
r.packed.packed_bytes,
214
100. 0 * r.packed.packed_bytes as f64 / r.packed.raw_bytes.max ( 1 ) as f64
d02e545d Andy McCall 1 month ago ↶
215
) ;
216
}
135212de Andy McCall 1 month ago ↶
217
println! ( " {} reachable; pruned {} ({} bytes){} {} ; {} present." ,
ba160f60 Andy McCall 1 month ago ↶
218
plural ( r.reachable, " object" ) ,
219
plural ( r.pruned.objects, " unreachable object" ) ,
220
r.pruned.bytes,
221
if r.pruned.deferred > 0 { format! ( " ; {} deferred by the grace period (use --now)" , plural ( r.pruned.deferred, " object" ) ) } else { String :: new( ) } ,
135212de Andy McCall 1 month ago ↶
222
if r.merged_packs > 0 { format! ( " ; merged {} into one" , plural ( r.merged_packs, " pack" ) ) } else { String :: new( ) } ,
ba160f60 Andy McCall 1 month ago ↶
223
plural ( repo.store ( ) .pack_count ( ) , " pack" )
224
) ;
d02e545d Andy McCall 1 month ago ↶
225
Ok ( 0 )
226
}
614541c3 Andy McCall 1 month ago ↶
227
228
229
fn current_head ( repo : & Repo) -> Result< oxy_core:: hash:: ChangeHash> {
230
let snap = repo.snapshot ( " oxy" ) ? ;
231
let base = snap.base.maximal ( & snap.wc.deps) ;
232
match base.as_slice ( ) {
233
[ h] => Ok ( * h) ,
234
_ => anyhow:: bail! ( " the working copy sits on {} heads; name the change explicitly" , base.len ( ) ) ,
235
}
236
}
237
238
pub fn describe ( message : & str , change : Option< & str > ) -> Result< i32 > {
239
let repo = open ( ) ? ;
240
let h = match change {
241
Some ( c) => repo.resolve_change ( c) ? ,
242
None => current_head ( & repo) ? ,
243
} ;
244
let new = repo.describe ( & h, message) ? ;
245
let c = repo.store ( ) .get_change ( & new) ? ;
135212de Andy McCall 1 month ago ↶
246
println! ( " {} {} {} {} " , ui:: ok( " Described" ) , ui:: id( short_id ( & c) ) , ui:: hash( format! ( " #{} " , new.short ( 12 ) ) ) , message.lines ( ) .next ( ) .unwrap_or ( " " ) ) ;
614541c3 Andy McCall 1 month ago ↶
247
Ok ( 0 )
248
}
249
23b217d7 Andy McCall 1 month ago ↶
250
pub fn amend ( message : Option< & str > , into : Option< & str > ) -> Result< i32 > {
614541c3 Andy McCall 1 month ago ↶
251
let repo = open ( ) ? ;
23b217d7 Andy McCall 1 month ago ↶
252
let new = match into {
253
Some ( spec) => {
254
let target = repo.resolve_change ( spec) ? ;
255
repo.amend_into ( & target, message) ?
256
}
257
None => repo.amend ( message) ? ,
258
} ;
614541c3 Andy McCall 1 month ago ↶
259
let c = repo.store ( ) .get_change ( & new) ? ;
135212de Andy McCall 1 month ago ↶
260
println! ( " {} {} {} {} " , ui:: ok( " Amended" ) , ui:: id( short_id ( & c) ) , ui:: hash( format! ( " #{} " , new.short ( 12 ) ) ) , c.message.lines ( ) .next ( ) .unwrap_or ( " " ) ) ;
614541c3 Andy McCall 1 month ago ↶
261
Ok ( 0 )
262
}
263
264
pub fn abandon ( change : & str ) -> Result< i32 > {
265
let repo = open ( ) ? ;
266
let h = repo.resolve_change ( change) ? ;
267
let c = repo.store ( ) .get_change ( & h) ? ;
268
repo.abandon ( & h) ? ;
269
println! ( " Abandoned {} #{} ; its content remains on disk as uncommitted work if the working copy sat on it." , short_id ( & c) , h.short ( 12 ) ) ;
270
Ok ( 0 )
271
}
252e8cb2 Andy McCall 1 month ago ↶
272
273
pub fn checkpoint ( ) -> Result< i32 > {
274
let repo = open ( ) ? ;
135212de Andy McCall 1 month ago ↶
275
let sp = ui:: spinner( " Writing checkpoint…" ) ;
252e8cb2 Andy McCall 1 month ago ↶
276
let ( r, changes, bytes) = repo.checkpoint ( ) ? ;
135212de Andy McCall 1 month ago ↶
277
sp.done ( & format! ( " {} {} of {} ({} bytes) for {} " , ui:: ok( " Checkpoint" ) , ui:: hash( format! ( " #{} " , r.short ( 12 ) ) ) , plural ( changes, " change" ) , bytes, ui:: id( & repo.config.bookmark) ) ) ;
278
Ok ( 0 )
279
}
280
281
282
pub fn prompt ( format : & str ) -> Result< i32 > {
283
let Ok ( repo) = Repo:: open( & std:: env:: current_dir( ) ? ) else { return Ok ( 1 ) } ;
284
let info = repo.quick_status ( ) ? ;
285
println! ( " {} " , info.format ( format) ) ;
252e8cb2 Andy McCall 1 month ago ↶
286
Ok ( 0 )
287
}
7421309f Andy McCall 1 month ago ↶
288
289
pub fn sparse ( paths : & [String]) -> Result< i32 > {
290
let mut repo = open ( ) ? ;
291
if paths.is_empty ( ) {
292
if repo.config.sparse_paths.is_empty ( ) {
293
println! ( " No sparse filter: the whole tree is materialized." ) ;
294
} else {
295
println! ( " {} " , ui:: heading( " Sparse filter" ) ) ;
296
for p in & repo.config.sparse_paths {
297
println! ( " {} " , ui:: path( p) ) ;
298
}
299
}
300
return Ok ( 0 ) ;
301
}
302
let snap = repo.snapshot ( " oxy sparse" ) ? ;
303
if ! snap.wc.tree_ops.is_empty ( ) | | ! snap.wc.edits.is_empty ( ) {
304
anyhow:: bail! ( " the working copy has changes; commit them before changing the sparse filter" ) ;
305
}
306
repo.config.set ( " filter.paths" , & paths.join ( " ," ) ) ? ;
307
repo.save_config ( ) ? ;
308
let heads = repo.bookmark_heads ( ) ? ;
309
let sp = ui:: spinner( " Re-checking out with the new filter…" ) ;
310
let r = repo.checkout ( & heads, true , " oxy sparse (checkout)" ) ? ;
311
sp.done ( & format! ( " {} {} : {} written, {} removed" , ui:: ok( " Sparse filter set to" ) , ui:: path( paths.join ( " ," ) ) , plural ( r.written, " file" ) , r.removed) ) ;
312
Ok ( 0 )
313
}
132b884b Andy McCall 1 month ago ↶
314
315
pub fn tag_create ( name : & str , changes : & [String], message : & str ) -> Result< i32 > {
316
let repo = open ( ) ? ;
317
repo.snapshot ( " oxy tag" ) ? ;
318
let heads = if changes.is_empty ( ) {
319
repo.bookmark_heads ( ) ?
320
} else {
321
let mut heads = Vec :: new( ) ;
322
for c in changes {
323
heads.extend ( repo.resolve_heads ( c) ? ) ;
324
}
325
heads
326
} ;
327
let t = repo.tag_create ( name, & heads, message) ? ;
328
println! (
329
" {} {} -> {} ({} ){} " ,
330
ui:: ok( " Tagged" ) ,
331
ui:: id( & t.name) ,
332
ui:: hash( format! ( " #{} " , t.state.short ( 12 ) ) ) ,
333
plural ( t.heads.len ( ) , " head" ) ,
334
t.signer.map ( | s | format! ( " , signed by {s} " ) ) .unwrap_or_else ( | | ui:: dim( " , unsigned" ) )
335
) ;
336
Ok ( 0 )
337
}
338
339
pub fn tag_list ( ) -> Result< i32 > {
340
let repo = open ( ) ? ;
341
let tags = repo.tags ( ) ? ;
342
if tags.is_empty ( ) {
343
println! ( " {} " , ui:: dim( " No tags." ) ) ;
344
}
345
for t in tags {
346
println! (
347
" {} {} {} {} {} " ,
348
ui:: id( & t.name) ,
349
ui:: hash( format! ( " #{} " , t.state.short ( 12 ) ) ) ,
350
ui:: dim( format! ( " ({} )" , plural ( t.heads.len ( ) , " head" ) ) ) ,
351
if t.message.is_empty ( ) { String :: new( ) } else { format! ( " {} " , t.message.lines ( ) .next ( ) .unwrap_or ( " " ) ) } ,
352
t.signer.map ( | s | ui:: dim( format! ( " [{s} ]" ) ) ) .unwrap_or_default ( )
353
) ;
354
}
355
Ok ( 0 )
356
}
4e88e774 Andy McCall 1 month ago ↶
357
358
pub fn workspace_add ( path : & std:: path:: Path, changes : & [String]) -> Result< i32 > {
359
let repo = open ( ) ? ;
360
let heads = if changes.is_empty ( ) {
361
None
362
} else {
363
let mut heads = Vec :: new( ) ;
364
for c in changes {
365
heads.extend ( repo.resolve_heads ( c) ? ) ;
366
}
367
Some ( heads)
368
} ;
369
let sp = ui:: spinner( & format! ( " Creating workspace at {} …" , path.display ( ) ) ) ;
370
let ws = repo.workspace_add ( path, heads.as_deref ( ) ) ? ;
371
sp.done ( & format! ( " {} {} (workspace {} )" , ui:: ok( " Workspace created at" ) , ui:: path( ws.root ( ) .display ( ) ) , ui:: id( ws.workspace ( ) .short ( 8 ) ) ) ) ;
372
Ok ( 0 )
373
}
374
375
pub fn workspace_list ( ) -> Result< i32 > {
376
let repo = open ( ) ? ;
377
for w in repo.workspaces ( ) ? {
378
println! (
379
" {} {} {} {} " ,
380
if w.current { ui:: ok( " *" ) } else { " " .into ( ) } ,
381
ui:: id( w.id.short ( 8 ) ) ,
382
ui:: path( w.path.display ( ) ) ,
383
w.working_copy.map ( | h | ui:: dim( format! ( " wc #{} " , h.short ( 12 ) ) ) ) .unwrap_or_else ( | | ui:: warn( " (not in view)" ) )
384
) ;
385
}
386
Ok ( 0 )
387
}
388
389
pub fn workspace_forget ( spec : & str ) -> Result< i32 > {
390
let repo = open ( ) ? ;
391
let all = repo.workspaces ( ) ? ;
392
let target = std:: fs:: canonicalize( spec) .ok ( ) ;
393
let matches: Vec< _ > = all.iter ( ) .filter ( | w | w.id.starts_with_hex ( spec) | | target.as_ref ( ) .is_some_and ( | t | * t = = w.path) ) .collect ( ) ;
394
let w = match matches.as_slice ( ) {
395
[ w] => * w,
396
[ ] => anyhow:: bail! ( " no workspace matches {spec:?}" ) ,
397
_ => anyhow:: bail! ( " {spec:?} is ambiguous" ) ,
398
} ;
399
repo.workspace_forget ( & w.id) ? ;
400
println! ( " {} workspace {} at {} ; its files were left in place." , ui:: ok( " Forgot" ) , ui:: id( w.id.short ( 8 ) ) , ui:: path( w.path.display ( ) ) ) ;
401
Ok ( 0 )
402
}
cdb5beba Andy McCall 1 month ago ↶
403
404
pub fn lock ( path : & str ) -> Result< i32 > {
405
let repo = open ( ) ? ;
406
repo.lock_path ( path) ? ;
407
println! ( " {} {} (advisory, local)" , ui:: ok( " Locked" ) , ui:: path( path) ) ;
408
Ok ( 0 )
409
}
410
411
pub fn unlock ( path : & str ) -> Result< i32 > {
412
let repo = open ( ) ? ;
413
repo.unlock_path ( path) ? ;
414
println! ( " {} {} " , ui:: ok( " Unlocked" ) , ui:: path( path) ) ;
415
Ok ( 0 )
416
}
23b217d7 Andy McCall 1 month ago ↶
417
418
pub fn split ( change : & str , paths : & [String]) -> Result< i32 > {
419
let repo = open ( ) ? ;
420
let h = repo.resolve_change ( change) ? ;
421
let ( h1, h2) = repo.split ( & h, paths) ? ;
422
let c1 = repo.store ( ) .get_change ( & h1) ? ;
423
let c2 = repo.store ( ) .get_change ( & h2) ? ;
424
println! ( " {} into {} {} and {} {} " , ui:: ok( " Split" ) , ui:: id( short_id ( & c1) ) , ui:: hash( format! ( " #{} " , h1.short ( 12 ) ) ) , ui:: id( short_id ( & c2) ) , ui:: hash( format! ( " #{} " , h2.short ( 12 ) ) ) ) ;
425
Ok ( 0 )
426
}