88#include "run-command.h"
99#include "sigchain.h"
1010#include "refs.h"
11+ #include "utf8.h"
12+ #include "worktree.h"
1113
1214static const char * const worktree_usage [] = {
1315 N_ ("git worktree add [<options>] <path> <branch>" ),
1416 N_ ("git worktree prune [<options>]" ),
17+ N_ ("git worktree list [<options>]" ),
1518 NULL
1619};
1720
@@ -359,6 +362,89 @@ static int add(int ac, const char **av, const char *prefix)
359362 return add_worktree (path , branch , & opts );
360363}
361364
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+
362448int cmd_worktree (int ac , const char * * av , const char * prefix )
363449{
364450 struct option options [] = {
@@ -371,5 +457,7 @@ int cmd_worktree(int ac, const char **av, const char *prefix)
371457 return add (ac - 1 , av + 1 , prefix );
372458 if (!strcmp (av [1 ], "prune" ))
373459 return prune (ac - 1 , av + 1 , prefix );
460+ if (!strcmp (av [1 ], "list" ))
461+ return list (ac - 1 , av + 1 , prefix );
374462 usage_with_options (worktree_usage , options );
375463}
0 commit comments