Is it possible to configure the ls command so that, when I use ls -l, it appends the git branch name after the directory name, if the directory is a git repository?

This way I can quickly find git repositories under the current directory as well as their working status.

Something like this:

-rw-rw-r--  1 michael michael    8 Aug 26 02:07 a-file
drwxrwxr-x  3 michael michael 4096 Aug 26 02:07 a-repo/ (master)
drwxrwxr-x  2 michael michael 4096 Aug 26 02:07 not-a-repo/

Note: I'm not looking to show git branch for the current directory or as part of the shell prompt, which I already know how.

  • 3
    I'm thinking you'd have to write your own code snippet for this, as I'd assume that if one exists, the user who wrote it will not see this, and will most likely not have publicly released it
    – David
    Commented Aug 26, 2017 at 9:19

3 Answers 3


I wrote a little Bash function using mainly awk to process the output of ls and append git branch names to directories, if they are part of repositories.


To install the function, simply copy the line below and append it to the end of your ~/.bashrc file. You have to source .bashrc after that or restart the shell session for the change to take effect.

lg (){ ls -alF "$@"|awk '{match($0,/^(\S+\s+){8}(.+)$/,f);b="";c="git -C \""f[2]"\" branch 2>/dev/null";while((c|getline g)>0){if(match(g,/^\* (.+)$/,a)){b="("a[1]")"}};close(c);print$0,b}';}

After that, you will have a new command lg available that behaves like the default ll alias (actually ls -alF), but with the appended current git branch.

Example usage:

Here is some example output, not the branch names in braces behind git1/ and git2/:

$ lg
total 48 
drwxrwxr-x 12 bytecommander bytecommander 4096 Aug 26 14:48 ./ 
drwxr-xr-x 74 bytecommander bytecommander 4096 Aug 26 15:30 ../ 
drwxrwxr-x  6 bytecommander bytecommander 4096 Aug 26 14:43 git1/ (master)
drwxrwxr-x  7 bytecommander bytecommander 4096 Aug 26 14:42 git2/ (develop)
drwxrwxr-x  4 bytecommander bytecommander 4096 Aug 26 14:45 no-git/ 
-rw-rw-r--  1 bytecommander bytecommander    0 Aug 26 14:42 regular-file 

The lg command still accepts all kinds of arguments, just like ls does. You can e.g. run lg -h, lg ~/projects, lg .. etc.


  • Fixed issue with filenames containing spaces or starting with #.

Known bugs and drawbacks:

  • The output will not be colored unlike the default ls output (e.g. directories are blue, executables green, symlinks cyan, ...).
  • It can not handle file names with newline characters in them. They will be displayed, but no branch info is shown.
  • The ls output will always be correct and display information about the path you specify as argument (if any, otherwise current directory as default). However, the branch information for the ./ and ../ entries is always relative to the current working directory, not the specified directory.
  • If you run this inside a repository, every subdirectory will also get the branch appended. The function does not distinguish between repository root directories and any repository subdirectories.

If you encounter more problems or happen to know a solution for one of the listed issues, feel free to leave a comment.

  • Filenames with newline characters in them, while technically valid, should be considered 'invalid' I believe. They tend to break a lot of things :P
    – Thomas Ward
    Commented Aug 26, 2017 at 16:32
  • Thank you for your answer. However, since there is no built-in way to do it, I'm considering writing a Python program myself, as it can be more flexible than awk Commented Aug 27, 2017 at 0:39

OK... Seeing that there is no built-in way to do it, I went ahead and wrote my own Python program. You can get it with pip:

pip3 install mklibpy-bin

Currently only support Python3.

GitHub link


I expanded the script form Byte Commander.

My version shows how many commits your branch is ahead or behind remote.

It also first fetches the changes.

lg() {
  ls -alF "$@"|awk '{
    git -C "f[2]" fetch;
    c="git -C \""f[2]"\" branch -v 2>/dev/null";
    while((c|getline g)>0){
      if(match(g,/^\* (\S+)/,a)){
      if(match(g,/^\*(.*)\[(.*)ahead ([0-9]+)(.*)\]/,u)){
        e="+"u[2]" ";
        d=d e
      if(match(g,/^\*(.*)\[(.*)behind ([0-9]+)(.*)\]/,v)){
        d=d e
      if(d == "") {

Edit: fixed regex.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .