Thompson
Thompson

Reputation: 2000

How to go to a folder in shell script and do the operation

I have a directory at server path - /home/user/repos where all my project folders are placed. like project-a, project-b, project-c etc. And this gitpull.sh file where I have placed below code is at path /home/user/automation/git/gitpull.sh

Now my requirement is this: I want to automate the git pull of all projects at certain time every day which I will set in CRON. But the issue I am facing is the file which I will put in CRON is not working.

I have created a shell script to pull all git repositories from the current directory, which is working fine. But unable to understand how to do git pull from a specified directory's subdirectories, (which is /home/user/repos in my case):

I have written the below code:

#!/bin/bash

REPOSITORIES="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

IFS=$'\n'

for REPO in `ls "$REPOSITORIES/"`
do
    if [ -d "$REPOSITORIES/$REPO" ]
    then
        echo "Updating $REPOSITORIES/$REPO at `date`"
        if [ -d "$REPOSITORIES/$REPO/.git" ]
        then
            cd "$REPOSITORIES/$REPO"
            git status
            echo "Fetching"
            git fetch
            echo "Pulling"
            git pull
        else
            echo "Skipping because it doesn't look like it has a .git folder."
        fi
        echo "Done at `date`"
        echo
    fi
done

I tried writing

REPOSITORIES="$( cd "/home/user/repos/")"

and

REPOSITORIES="$( cd "/home/user/repos/*")"

But nothing worked.

Upvotes: 0

Views: 2828

Answers (2)

MarcoLucidi
MarcoLucidi

Reputation: 2177

you can use the -C option of git. from man git:

-C path

Run as if git was started in path instead of the current working directory. When multiple -C options are given, each subsequent non-absolute -C path is interpreted relative to the preceding -C path.

...

for example:

#!/bin/sh

REPOSITORIES="/home/user/repos"

for repo in "$REPOSITORIES"/*/; do
        echo "Updating $repo at `date`"
        if [ -d "$repo/.git" ]; then
                git -C "$repo" status
                echo "Fetching"
                git -C "$repo" fetch
                echo "Pulling"
                git -C "$repo" pull
        else
                echo "Skipping because it doesn't look like it has a .git folder."
        fi
        echo "Done at `date`"
        echo
done

the line:

for repo in "$REPOSITORIES"/*/; do

allows you to iterate over just directories, then if it contains a git repository, run the git commands on that directory.

edit: added directory base path

Upvotes: 2

user2876414
user2876414

Reputation: 25

Can you be more specific about what isn't working? Is the script doing anything at all?

Is the script in the repos directory?

REPOSITORIES="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

gets you the directory where actual script is, not the directory where you run it from.

REPOSITORIES="$( cd "/home/user/repos/")"

won't work because you're just starting a subshell, changing directories, then not actually outputting anything. If you just want to hardcode the directory name, then do this:

REPOSITORIES="/home/user/repos"

Also, iterating over the output of ls is bad practice, ls output isn't designed to be parsed programmatically. Use

for REPO in "$REPOSITORIES"/*

Upvotes: 0

Related Questions