8
8
#include "run-command.h"
9
9
#include "sigchain.h"
10
10
#include "refs.h"
11
+ #include "utf8.h"
12
+ #include "worktree.h"
11
13
12
14
static const char * const worktree_usage [] = {
13
15
N_ ("git worktree add [<options>] <path> <branch>" ),
14
16
N_ ("git worktree prune [<options>]" ),
17
+ N_ ("git worktree list [<options>]" ),
15
18
NULL
16
19
};
17
20
@@ -359,6 +362,89 @@ static int add(int ac, const char **av, const char *prefix)
359
362
return add_worktree (path , branch , & opts );
360
363
}
361
364
365
+ static void show_worktree_porcelain (struct worktree * wt )
366
+ {
367
+ printf ("worktree %s\n" , wt -> path );
368
+ if (wt -> is_bare )
369
+ printf ("bare\n" );
370
+ else {
371
+ printf ("HEAD %s\n" , sha1_to_hex (wt -> head_sha1 ));
372
+ if (wt -> is_detached )
373
+ printf ("detached\n" );
374
+ else
375
+ printf ("branch %s\n" , wt -> head_ref );
376
+ }
377
+ printf ("\n" );
378
+ }
379
+
380
+ static void show_worktree (struct worktree * wt , int path_maxlen , int abbrev_len )
381
+ {
382
+ struct strbuf sb = STRBUF_INIT ;
383
+ int cur_path_len = strlen (wt -> path );
384
+ int path_adj = cur_path_len - utf8_strwidth (wt -> path );
385
+
386
+ strbuf_addf (& sb , "%-*s " , 1 + path_maxlen + path_adj , wt -> path );
387
+ if (wt -> is_bare )
388
+ strbuf_addstr (& sb , "(bare)" );
389
+ else {
390
+ strbuf_addf (& sb , "%-*s " , abbrev_len ,
391
+ find_unique_abbrev (wt -> head_sha1 , DEFAULT_ABBREV ));
392
+ if (!wt -> is_detached )
393
+ strbuf_addf (& sb , "[%s]" , shorten_unambiguous_ref (wt -> head_ref , 0 ));
394
+ else
395
+ strbuf_addstr (& sb , "(detached HEAD)" );
396
+ }
397
+ printf ("%s\n" , sb .buf );
398
+
399
+ strbuf_release (& sb );
400
+ }
401
+
402
+ static void measure_widths (struct worktree * * wt , int * abbrev , int * maxlen )
403
+ {
404
+ int i ;
405
+
406
+ for (i = 0 ; wt [i ]; i ++ ) {
407
+ int sha1_len ;
408
+ int path_len = strlen (wt [i ]-> path );
409
+
410
+ if (path_len > * maxlen )
411
+ * maxlen = path_len ;
412
+ sha1_len = strlen (find_unique_abbrev (wt [i ]-> head_sha1 , * abbrev ));
413
+ if (sha1_len > * abbrev )
414
+ * abbrev = sha1_len ;
415
+ }
416
+ }
417
+
418
+ static int list (int ac , const char * * av , const char * prefix )
419
+ {
420
+ int porcelain = 0 ;
421
+
422
+ struct option options [] = {
423
+ OPT_BOOL (0 , "porcelain" , & porcelain , N_ ("machine-readable output" )),
424
+ OPT_END ()
425
+ };
426
+
427
+ ac = parse_options (ac , av , prefix , options , worktree_usage , 0 );
428
+ if (ac )
429
+ usage_with_options (worktree_usage , options );
430
+ else {
431
+ struct worktree * * worktrees = get_worktrees ();
432
+ int path_maxlen = 0 , abbrev = DEFAULT_ABBREV , i ;
433
+
434
+ if (!porcelain )
435
+ measure_widths (worktrees , & abbrev , & path_maxlen );
436
+
437
+ for (i = 0 ; worktrees [i ]; i ++ ) {
438
+ if (porcelain )
439
+ show_worktree_porcelain (worktrees [i ]);
440
+ else
441
+ show_worktree (worktrees [i ], path_maxlen , abbrev );
442
+ }
443
+ free_worktrees (worktrees );
444
+ }
445
+ return 0 ;
446
+ }
447
+
362
448
int cmd_worktree (int ac , const char * * av , const char * prefix )
363
449
{
364
450
struct option options [] = {
@@ -371,5 +457,7 @@ int cmd_worktree(int ac, const char **av, const char *prefix)
371
457
return add (ac - 1 , av + 1 , prefix );
372
458
if (!strcmp (av [1 ], "prune" ))
373
459
return prune (ac - 1 , av + 1 , prefix );
460
+ if (!strcmp (av [1 ], "list" ))
461
+ return list (ac - 1 , av + 1 , prefix );
374
462
usage_with_options (worktree_usage , options );
375
463
}
0 commit comments