Automatically launch command when cd into a choosen directory - bash

I would like to launch : $ git status
when I cd into ~/work
I thought about putting an alias that would cd me into the work directory and launch the git status, but I don't find that solution to be optimal.

Add this to your .bashrc:
gitstatusinwork() {
if [[ "$PWD" != "$MYOLDPWD" ]]; then
MYOLDPWD="$PWD"
if [[ "$PWD/" = ~/work/* ]]; then
if [[ "$OLDPWD" != ~/work/* && "$INWORKDIR" == 0 ]]; then
git status
fi
INWORKDIR=1
else
INWORKDIR=0
fi
fi
}
export PROMPT_COMMAND="$PROMPT_COMMAND; gitstatusinwork"
This function executes git status as soon as your enter your ~/work directory (or any of its subdirectory), then never displays it again, unless you get out of the ~/work directory and re-enter it again.

The easiest way is:
cd ~/work && git status
I don't think you're looking for this though.
Another option would be overwriting the default cd command. You could place a bash function at the end of your .bashrc or .bash_profile file like so:
cd() {
builtin cd "$1"
# detect if the current directory is a git repository
if [ -d .git ] || git rev-parse --is-inside-work-tree 2> /dev/null > /dev/null; then
echo ""; git status
fi
}
I hope this helps.
Update:
If you just want to see the git status when you cd into the root of your repo, you can just use the first part of the conditional like so:
cd() {
builtin cd "$1"
# detect if the current directory is a git repository
if [ -d .git ]; then
echo ""; git status
fi
}

Related

How to remove git bash ssh authentication on windows

Whenever i go to do some operation on Windows involving my remote repository like git pull, git remote update or git push (among others) Windows keeps asking me to inform my SSH key. Is there any way to stop this?
Yes. As described at: https://docs.github.com/en/authentication/connecting-to-github-with-ssh/working-with-ssh-key-passphrases#auto-launching-ssh-agent-on-git-for-windows
You can run ssh-agent automatically when opening bash or the Git
shell. Copy the following lines and paste them into the ~/.profile
or ~/.bashrc file in Git Shell:
# Auto-launching ssh-agent on Git for Windows
env=~/.ssh/agent.env
agent_load_env () { test -f "$env" && . "$env" >| /dev/null ; }
agent_start () {
(umask 077; ssh-agent >| "$env")
. "$env" >| /dev/null ; }
agent_load_env
# agent_run_state: 0=agent running w/ key; 1=agent w/o key; 2=agent not running
agent_run_state=$(ssh-add -l >| /dev/null 2>&1; echo $?)
if [ ! "$SSH_AUTH_SOCK" ] || [ $agent_run_state = 2 ]; then
agent_start
ssh-add
elif [ "$SSH_AUTH_SOCK" ] && [ $agent_run_state = 1 ]; then
ssh-add
fi
unset env
But in my case I didn't have those files mentioned so what I did was create in my C:\Users\<username> directory a file called .bashrc and paste the code indicated.
It could be that the first time you open your git bash or try to do some operation involving the remote it will ask you for your password, but after you enter this first time it will not ask for any more.

bash, script to git add one file and commit

I'm trying to create a script to do this:
git add "file"
git commit -m "Comment"
My idea is to run:
gac "file" "Comment"
I know I can do something similar but for all files, with:
echo 'alias gac="/path/to/gitaddcommit.sh"' >> ~/.bash_profile
And the .sh would be:
!/bin/bash
git add .
echo “Enter commit message: “
git commit -am “$commitMessage”
Well you need two things :
A bin folder where you can put every sh script you want to use everywhere.
More knowledge about shell scripting and how you can get argv (in your ex: 'file' 'Comment')
So first go to your /home/<username> then mkdir bin && cd bin && pwd
then copy the pwd and add it into your PATH env variable inside your .bashrc
path example: PATH='/bin/:/sbin/:/home//bin
Then source ~/.bashrc you can now use every sh script inside you bin folder everywhere.
Cool so first problem done !
you don't have to do echo alias gac="/path/to/gitaddcommit.sh"' >> ~/.bash_profile anymore.
Now second problem here a post that can help you post
And let me show you for your example :
cd ~/bin && vi gac.sh
Now the script :
#!/bin/sh
if [ "$#" -ne 2 ]; then
echo "Usage: ./gac FILENAME COMMIT_MESSAGE" >&2
exit 1
fi
git add "$1"
git commit -am "$2"
First we check the number or arg then git add and commit.
Simple and fast maybe checking if arg one is a file might be a good idea too.
PS: i'm going to re write my post ahah
Here's what I have in my .bashrc:
ga ()
{
if test "$1" != "-f" && git rev-parse HEAD > /dev/null 2>&1 && ! git diff-index --quiet HEAD; then
echo 'Repo is dirty. -f to force' 1>&2;
return 1;
fi;
git add "$#";
list=$(git diff --name-only --cached | tr \\n \ );
git commit -m "Add $list"
}
The commit message is autogenerated, but you could easily modify it to prompt the user or take it from somewhere else.

How can I find the root git directory reliably from a git hook?

Given 2 git repositories (Product A and Product B), with submodules (CommonSubmodule, SomeOtherSubmodule)
D:\Repositories\ProductA\
D:\Repositories\ProductA\CommonSubmodule
D:\Repositories\ProductA\SomeOtherSubmodule
D:\Repositories\ProductA\SomeOtherSubmodule\
D:\Repositories\ProductB\SomeOtherSubmodule\
D:\Repositories\ProductB\CommonSubmodule\
I've found a script online that allows for branches to be logged via a post_checkout hook
#!/bin/sh
previous_head_ref=$1
new_head_ref=$2
is_branch_checkout=$3
if [[ "$previous_head_ref" != "$new_head_ref" ]] && [[ "$is_branch_checkout" == 1 ]]; then
branch=$(git rev-parse --abbrev-ref HEAD)
#if [[ "develop" != "$branch" ]]; then
path="$(dirname "$0")/.."
logfile="$path/x_branch_log"
ts=$(date +%s)
echo "$branch|1|$ts" >> $logfile
echo "Logging $branch|1|$ts to $logfile"
echo PWD is $PWD
#fi
fi
In a post_checkout context, how can I get the root directory (D:\Repositories) no matter how deep in the submodule the hook is installed, without encoding absolute paths?
D:\Repositories\
Additionally, how can I get the root product directory, e.g.
D:\Repositories\ProductA\
D:\Repositories\ProductB\
From the comments I got on my answer on Git repo root folder, check the return value of a
git rev-parse --git-dir
You might have to iterate (if you are in a submodule of a submodule of a parent repo), but it should return the root folder of the parent repo.

How can I get git's `.git` path from git itself?

I am trying to write a shell script that needs to be able to find the .git folder for the current directory, correctly handling all of the following possibilities:
I might be in a bare repo, in which case the .git folder is either . or .. or ../.. or so on.
I might be in a submodule (in which I'll find a .git file that contains the path to the git folder)
$GIT_DIR might be set.
I might not be in a git repo at all
I have this:
seemsToBeGitdir() {
# Nothing special about "config --local -l" here, it's just a git
# command that errors out if the `--git-dir` argument is wrong.
git --git-dir "$1" config --local -l >/dev/null 2>/dev/null
return $?
}
gitdir() {
local cursor relpath
if [ "$GIT_DIR" ]; then
echo "$GIT_DIR"
return 0
fi
cursor="$(pwd)"
while [ -e "$cursor" ] && ! seemsToBeGitdir "$cursor"; do
# Git won't traverse mountpoints looking for .git
if mountpoint -q "$cursor"; then
return 1
fi
# We might be in a submodule
if [ -f "$cursor/.git" ]; then
# If .git is a file, its syntax is "gitdir: " followed by a
# relative path.
relpath="$(awk '/^gitdir:/{print$2}' "$cursor/.git")"
# convert the relative path to an absolute path.
cursor="$(readlink -f "$cursor/$relpath")"
continue
fi
if seemsToBeGitdir "$cursor/.git"; then
echo "$cursor/.git"
return 0
fi
cursor="$(dirname "$cursor")"
done
echo "$cursor"
}
And it works, but seems way too complicated -- clearly, git itself does this sort of calculation every time it's invoked. Is there a way to make git itself tell me where .git is?
Use git rev-parse, which has options specifically for this:
git rev-parse --git-dir
See also:
git rev-parse --absolute-git-dir
(new in Git version 2.13.0), and:
git rev-parse --show-toplevel
and:
git rev-parse --show-cdup
(note that its output is empty if you are already in the top level of the repository). View your own documentation to find out which options your Git supports; most of these have been around since Git 1.7, though.

Git Bash Script Check Working Tree

Is there a way in Git Bash to check if the working tree is clean, that is no uncommitted changes or untracked files?
I'm working on a bash script for my group to automate the process of daily rebasing working branches. Unclean working trees is a common problem. I can manually correct the problem by executing git checkout .. This would have the desired result most of the time, but not always, so I need to be able to have my script programatically check that the working directory/tree is clean.
The git-sh-setup script included with git contains a number of useful functions for working with git repositories. Among them is require_clean_work_tree:
require_clean_work_tree () {
git rev-parse --verify HEAD >/dev/null || exit 1
git update-index -q --ignore-submodules --refresh
err=0
if ! git diff-files --quiet --ignore-submodules
then
echo >&2 "Cannot $1: You have unstaged changes."
err=1
fi
if ! git diff-index --cached --quiet --ignore-submodules HEAD --
then
if [ $err = 0 ]
then
echo >&2 "Cannot $1: Your index contains uncommitted changes."
else
echo >&2 "Additionally, your index contains uncommitted changes."
fi
err=1
fi
if [ $err = 1 ]
then
test -n "$2" && echo >&2 "$2"
exit 1
fi
}
This is in addition to being able to check the output from git status --porcelain and/or git status -z if you need to be more specific about what the state currently is.

Resources