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!
How to Do It
- Open
.bashrc
. - 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
Top comments (23)
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.
That's too much. My own script in my repository (14k files) takes 0.1s.
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!
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.
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?
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.
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.
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.
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.
Incredibly! That's what hell looks like!
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.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.
Looks like a really cool option with some great beginner tutorials -- thanks for posting the link so interested parties can check it out!
Oh-my-zsh is pretty great.
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/XCsdhMnThat's very cool!
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.
Great tip! I'd love to learn what that PS1 means though
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.
but how does one make a prompt string -- the color, the spacing, referencing computer name/gitbranch/folder etc
Depends on your terminal. On my terminal, I hard code the ANSI escape sequences in my
~/.bash_profile
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.)
Where is
__git_ps1
?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.