DEV Community

loading...
Cover image for Display Git Branch Info In Bash Prompts

Display Git Branch Info In Bash Prompts

bunnyladame profile image Eva Deane ・1 min read

I can't even count how many times I run git branch during an average workday. With multiple tickets assigned to me across multiple projects, keeping track of exactly where I am in our codebase can be a real challenge -- especially in my case, where my short-term memory is affected by ADHD. But with just a few extra lines added to .bashrc, my current branch info is now right in my Bash prompt!

An example screenshot of the newly-modified command line showing that the current branch is up to date

How to Do It

  1. Open .bashrc.
  2. At the bottom of the file, add the following:
export GIT_PS1_SHOWDIRTYSTATE='y'
export GIT_PS1_SHOWSTASHSTATE='y'
export GIT_PS1_SHOWUNTRACKEDFILES='y'
export GIT_PS1_DESCRIBE_STYLE='contains'
export GIT_PS1_SHOWUPSTREAM='auto'
export PS1='\[\033[32m\]\u@\h\[\033[00m\]:\[\033[34m\]\w\[\033[31m\]$(__git_ps1)\[\033[00m\]\$

Save your changes and exit.

You may need to close and reopen your Bash prompt before the changes show up, but from now on, whenever you're in a local repo, you'll see the name of the current branch and its status right there on the command line.

Branch Status Cheat Sheet

=: Local branch is up to date with the remote version
*: Updated files need to be staged
+: Staged files need to be committed
>: Local branch is ahead of remote branch -- git push
<: Remote branch is ahead of local branch -- git pull
<>: Remote and local branches are in conflict or otherwise diverged

Discussion (23)

pic
Editor guide
Collapse
eljayadobe profile image
Eljay-Adobe

I had to roll my own (which I also called __git_ps1) which only displays which branch I'm in. The extra checking for the other state took too long. (I'm using Bash, I realize Zsh is a little more out-of-the-box capable for this kind of thing.)

I could spawn the extra checking off as a background and then display it on future prompts when the background checking concludes, since it takes about 10 seconds on my mammoth repo. But I've been too lazy so far.

Collapse
vlasales profile image
Vlastimil Pospichal

That's too much. My own script in my repository (14k files) takes 0.1s.

Collapse
eljayadobe profile image
Eljay-Adobe

That's certainly a much more reasonably sized repo! Some of the git gurus on the team are trying to figure out a way to better partition our enormous repo. In part that will entail re-organizing the code base using The Pitchfork Layout. I am highly anticipating that much needed change!

Thread Thread
vlasales profile image
Vlastimil Pospichal

I have some reservations about such practices, because a lot of ties that should have stayed together (meow.cpp, meow.hpp) are often broken. Instead of taxonomy, I split the application by domains.

Thread Thread
eljayadobe profile image
Eljay-Adobe

For instance... at one time, we had 12 copies of Boost. We still have 12 logical copies of boost, with 11 of the copies jury rigged to point (soft link) to the 12th. We should only have 1 copy of Boost, and that copy of Boost should not be "contained" as part of any deliverable from an upstream provider, rather it should be owned by main project (my project), and cited as a manifest dependency by the other 11 deliverables under Pitchfork.

Is that what you mean by splitting the application by domains?

Thread Thread
vlasales profile image
Vlastimil Pospichal

Can you have one Boost in a separate repository as a git submodule?

My domains are eg: User, Customer, Cart, Product, Order, Payment, Picture,... They are relative standalone.

Thread Thread
eljayadobe profile image
Eljay-Adobe

Can you have one Boost in a separate repository as a git submodule?

That is a possibility. We're doing submodules right now, as a temporary measure for some of our consumed deliverables from upstream (in-house) providers, and it seems they are not the best way to go for us.

The git gurus working on the Pitchfork Layout (which follows Lakos's suggestions from his mid-90s book) are looking into alternatives to submodules.

Thread Thread
vlasales profile image
Vlastimil Pospichal • Edited

What is problem with submodules?

I prefer flat structure of directories - 3rd level as maximum, eg. src/domain-name/subdir/. When you need a next level, you need split the domain or split the subdir or make a submodule.

The tree structure was once used in databases and has been mostly replaced by a relational structure. Similarly, the depth of directory trees needs to be radically reduced.

Thread Thread
eljayadobe profile image
Eljay-Adobe • Edited

I'm with you on your preference! Going a Pitchfork Layout will help flatten our structure of directories. Right now, we have many that are DOZENS of subdirectories deep. Not liking that at all.

I'm not sure I can describe the problem with submodules. It's as if they are "unplugged" from the main repository. They cause me problems about once a week, but other devs are running into frustration with them frequently. Maybe if our repository wasn't about 20 GB it'd be less of an annoyance.

Thread Thread
vlasales profile image
Vlastimil Pospichal

Incredibly! That's what hell looks like!

Thread Thread
eljayadobe profile image
Eljay-Adobe

laugh... yes, well, that's why we have a few of our devs dealing with how to partition the code base so that it isn't nearly as unwieldy. I should clarify, the git repo backing store itself (in the .git directory) is only about 4 GB. The rest of the code and libraries and resources (audio, images, video) is 20 GB (not including the .git directory). Most of the git repo is source, and not binaries. The binaries are stored elsewhere, and pulled down from a "ticket" (UUID or hash or whatever... some unique identifier).

Those numbers do not including the intermediary files (*.obj et cetera) as part of the build.

Collapse
xanderyzwich profile image
Corey McCarty

I was really interested in this, and as I was looking into it I was suggested by a friend to look at commandlinepoweruser.com/ and I wound up using zsh with that kind of thing baked in nicely. I highly recommend it.

Collapse
bunnyladame profile image
Eva Deane Author

Looks like a really cool option with some great beginner tutorials -- thanks for posting the link so interested parties can check it out!

Collapse
xanderyzwich profile image
Corey McCarty

Oh-my-zsh is pretty great.

Collapse
sayam753 profile image
Sayam Kumar

That's interesting. The terminals looks awesome with ohmyzsh. Personally, I like to manually configure zsh. This is how my terminal looks like ibb.co/XCsdhMn

Collapse
xanderyzwich profile image
Corey McCarty

That's very cool!

Collapse
phantas0s profile image
Matthieu Cneude • Edited

Nice article! Short and straight to the point, I like it :)

For the Zsh user, I've a very simple prompt without dependency displaying git info.

In general, if somebody wants to use Zsh without relying on big framework like Oh-my-zsh or Prezto, I wrote an article about that here.

Collapse
abdisalan_js profile image
Abdisalan

Great tip! I'd love to learn what that PS1 means though

Collapse
eljayadobe profile image
Eljay-Adobe

PS1 is the primary prompt string.

PS2 is the secondary prompt string.

PS3 is the prompt string for the select command.

PS4 is the prompt string for the execution trace.

Collapse
abdisalan_js profile image
Abdisalan

but how does one make a prompt string -- the color, the spacing, referencing computer name/gitbranch/folder etc

Thread Thread
eljayadobe profile image
Eljay-Adobe • Edited

Depends on your terminal. On my terminal, I hard code the ANSI escape sequences in my ~/.bash_profile

export PS1='\['$'\e[32m''\]\h:\W \u\$\['$'\e[0m''\] '

The trickier folks would use tput which would emit the ANSI escape sequences (or whatever sequences are appropriate for the current terminal) instead of hard coded ANSI sequences, but I'm not that tricky.

(I use a different prompt for working with git, but I'm on a different computer at the moment.)

Collapse
vlasales profile image
Vlastimil Pospichal

Where is __git_ps1?

Collapse
drhyde profile image
David Cantrell

Win!

I have something similar in my Mac's touchbar showing the name of the repo, the current branch, and the currently selected versions of a bunch of pre-requisites.