From: Jakub Narebski <jnareb@gmail.com>
To: "Stephen Sinclair" <radarsat1@gmail.com>
Cc: git@vger.kernel.org
Subject: Re: command prompt script for current branch
Date: Wed, 06 Feb 2008 13:09:50 -0800 (PST) [thread overview]
Message-ID: <m3r6fp4wrt.fsf@localhost.localdomain> (raw)
In-Reply-To: <9b3e2dc20802061152q63bc61acuaecf3f33d4df8b19@mail.gmail.com>
"Stephen Sinclair" <radarsat1@gmail.com> writes:
> Attached is a script I quickly wrote up yesterday. Sometimes I've
> found I started working only to realize I was on the wrong branch.
> (Now that I'm accustomed to working with git, I make many small
> branches, so it happens.)
First, it is much better to put such script inline, in the body of
your email. This makes commenting about script body much easier.
And if you have to attach it, for example because your mailer mangles
whitespace (which is not the case here), make sure that attachement
uses "text/plain", and if possible "inline" disposition, to better
_view_ the code without need to save it to temporary file.
I would take an exeption and comment on your code, even though you
make it hard to do so.
Second, there are numerous examples on how to create git-aware
prompt. Those include code in contrib/completion/git-completion.bash
in git sources:
# 4) Consider changing your PS1 to also show the current branch:
# PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
#
# The argument to __git_ps1 will be displayed only if you
# are currently in a git repository. The %s token will be
# the name of the current branch.
and the _git_ps1 file in sources of "Git In Nutshell", with git
repository at http://git.jonas.iki.fi/git_guides.git; this code
by yours truly is heavily commented to make it easier to understand.
I'm not sure if it is included in "Git In Nutshell"
(http://jonas.iki.fi/git_guides).
I have put the _git_ps1 code at the end of this post.
> So I made this small script to simply write the name of the currently
> checked out branch, as well as information on how many commits it
> differs from the remote tracking branch, if any.
> It also appends an exclamation mark if I have uncommitted changes. I
> stuck it in my PS1 environment variable, so that it would be part of
> my command prompt.
Third, the information on how many commits it differes from coupled
remote tracking branch is not that fast to get; additionally you don't
always _have_ coupled remote tracking branch. For me the number of
commits current branch differs from origin repo, and "dirtiness" of
branch are not important, while working with detached HEAD and marking
branches which are StGit controlled is.
> -- >8 --
> #!/bin/bash
>
> # exit if not a git repo
> if ! (git branch >/dev/null 2>&1); then
> exit
> fi
There are much better ways to do this; it is usually much better to
use plumbing (engine) commands in scripts, not porcelain, which is
meant for user interaction. See code in _git_ps1
Besides, why do you run git-branch _twice_?
> BRANCH=$(git branch | grep \* | sed s,\*\ ,, )
There is much better way to do this with plumbing.
> REMOTE=$(git config --list | grep branch.$BRANCH.remote 2>/dev/null | cut -f2 -d=)
> MERGE=$(git config --list | grep branch.$BRANCH.merge 2>/dev/null | sed s,^.*=refs/heads/,,)
Why do you use "git config --list" then grep for key, instead of
asking git-config to return results for given key with
"git config --get" or "git config --get-all"?
By the way, when you use grep you should quote '.', as '.' means any
character in regular expression. You do not need put regular
expression (parameter to grep) in double quotes _only_ because
refnames (and branchnames) cannot contain spaces.
Your code wouldn't be able to deal with being on detached HEAD.
> # exit if no branch found
> if [ "${BRANCH}"x == x ]; then
> exit
> fi
This is mixture of coding for portability with bash-isms; either use
'test' instead of '[', or use '-z' operator.
> echo -n ' '[$BRANCH
>
> # dirty state
> if [ "$(git-diff-index --name-only HEAD)"x != x ]; then
> echo -n \!
> fi
Err... if you want to check if there are differences, it would be
better to use '--quiet' (which implies '--exit-code') and check for
exit code instead of checking if there was any output.
BTW. there is slight inconsistency in using dashed (git-diff-index)
and dashless (git branch) of diff commands. In "external" script
which does not source git shell script "library", it is better to use
dashless form.
> # exit if no remote tracking branch found
> if [ ${REMOTE}x == x -a ${MERGE}x == x ]; then
> echo ]
> exit
> fi
>
> # Uncomment this line to ignore remote tracking branches
> # echo ]; exit
>
> # calc number of revs between remote and local
> FWDREVS=$(git rev-list $REMOTE/$MERGE..$BRANCH 2>/dev/null 2>&1 | wc -l)
>
> # and the other way, in case it is not up to date
> BACKREVS=$(git rev-list $BRANCH..$REMOTE/$MERGE 2>/dev/null 2>&1 | wc -l)
>
> echo -n ' '-\> $REMOTE/$MERGE
>
> if [ $FWDREVS -gt 0 ]; then
> echo -n +$FWDREVS
> fi
>
> if [ $BACKREVS -gt 0 ]; then
> echo -n -$BACKREVS
> fi
>
> echo ]
Why do you use sequence of "echo -n", instead of setting variables,
perhaps with the help of some more advanced constructs like in example
below, then using one "echo" to output it all?
-- >8 --
function _git_ps1()
{
# 'git_dir' is absolute path to git repository
# 'rel' is path relative to top dir in repository
# 'br' is current branch name, or 'HEAD' if we are on detached HEAD
local git_dir rel br
# first call to git-rev-parse also checks if we are inside git
# repository; if we are not in git repository, use default prompt,
# provided as an argument
rel=$(git rev-parse --show-prefix 2>/dev/null) || \
{ echo "$@" ; return; }
rel=${rel%\/}
# get branch name, strip 'refs/heads/' prefix,
# and use 'HEAD' for detached HEAD (no branch name)
br=$(git symbolic-ref HEAD 2>/dev/null)
br=${br#refs/heads/}
br=${br:-HEAD}
# path to top dir of git repository
loc=${PWD%/$rel}
# the following code is important only if you use StGit,
# to note if you are on StGit controlled branch;
# use second part of conditional if you don't use StGit
git_dir=$(git rev-parse --git-dir)
if [ "$br" -a -e "$git_dir/patches/$br" ]; then
echo "$br:${loc/*\/}${rel:+/$rel}# "
else
echo "$br:${loc/*\/}${rel:+/$rel}> "
fi
}
## bash:
## set PS1 only if we are in interactive shell (PS1 is set)
# [ "$PS1" ] && PS1='$(_git_ps1 "\u@\h:\w> ")'
## zsh:
# function precmd() {
# PS1=`_git_ps1 '%m:%~%# '`
# }
# vim:filetype=sh
--
Jakub Narebski
Poland
ShadeHawk on #git
next prev parent reply other threads:[~2008-02-06 21:10 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-02-06 19:52 command prompt script for current branch Stephen Sinclair
2008-02-06 20:42 ` Junio C Hamano
2008-02-06 22:14 ` [PATCH (repost)] Improve bash prompt to detect merge / rebase in progress Robin Rosenberg
2008-02-06 22:23 ` Robin Rosenberg
2008-02-06 22:31 ` Junio C Hamano
2008-02-07 0:23 ` Robin Rosenberg
2008-02-07 6:34 ` Shawn O. Pearce
2008-02-08 11:26 ` Steffen Prohaska
2008-02-08 12:25 ` Johannes Schindelin
2008-02-08 13:12 ` Steffen Prohaska
2008-02-08 14:06 ` [PATCH/RFC] Make git-completion.bash a first-class citizen Johannes Schindelin
2008-02-06 23:21 ` [PATCH (repost)] Improve bash prompt to detect merge / rebase in progress Jakub Narebski
2008-02-06 23:44 ` Mike Hommey
2008-02-06 21:09 ` Jakub Narebski [this message]
2008-02-06 22:13 ` command prompt script for current branch Stephen Sinclair
2008-02-06 22:56 ` Jakub Narebski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=m3r6fp4wrt.fsf@localhost.localdomain \
--to=jnareb@gmail.com \
--cc=git@vger.kernel.org \
--cc=radarsat1@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).