0

I have a repository on GitHub that I created and it has a bunch of bash scripts that my team and I are using. However, I want to be sure that they are using the most up-to-date scripts at all times. Whenever I make an update to the remote, I find myself calling them up telling them to do a pull from the remote. This seems very inefficient.

I browsed the internet endlessly looking for a solution - some kind of PC tool (we use Windows) that just automatically checks if the local repo is up-to-date or not and if not, it automatically pulls from the remote.

I couldn't find anything so if someone has a solution for this I'd appreciate it.

Eyal Gerber
  • 1,026
  • 10
  • 27
  • 3
    Git is a version control tool that helps in development. You're using it for deployment/distribution, there are deployment and distribution tools and strategies unrelated to Git that might solve your problem. – choroba Jun 29 '21 at 15:28
  • @choroba do you have suggestions for such deployment tools? I'd be happy to learn... Thanks. – Eyal Gerber Jun 30 '21 at 08:52

1 Answers1

0

I eventually created a solution for myself that is not EXACTLY what I was looking for but does solve the problem for me:

I just introduced to ALL my scripts in the repo a call to a function that just checks if the repo is in sync with the remote. If it is not, it does not let the scripts continue and the script aborts, forcing the users to pull from the remote before running the scripts. So this way, I know no one will be using an out-of-date version of my scripts.

Here is the script I used (I put it in a file called GlobalFunctions.sh within the repo with all the other bash scripts):

#!/bin/bash
#------------------------------------------------------
# GlobalFunctions.sh
# Description:
# This file is supposed to serve as a file for global bash script functions that could be used by multiple files. 
#-------------------------------------------------------------

#verify that the repository containing the scripts is up-to-date
function CheckScriptsValidity()
{
    # DIRECTORY WHERE THE SCRIPT IS LOCATED
    SCRIPT_DIRECTORY="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
    
    # CURRENT DIRECTORY
    ORIGINAL_DIRECTORY=$(pwd)
    
    cd $SCRIPT_DIRECTORY
    
    git fetch  #update the branch origin/main
    if [[ -z $(git diff origin/main..HEAD) ]]   # if the current location (HEAD) is at the same location as the remote main branch
    then
        echo "Scripts Repo is up to date."
    else
        echo "Scripts Repo is not up to date with remote. Please pull Scripts repo from remote. Aborting..."
        read -p "Press enter to continue..."
        exit 0
    fi
    
    cd $ORIGINAL_DIRECTORY
}

CheckScriptsValidity        #Verify that the repository containing the scripts is up-to-date

And within each bash script file I simply added this line on top:

source $(dirname "$0")/GlobalFunctions.sh   #Load script file so that we can call its functions (path defined based on this: https://stackoverflow.com/a/42101141/4441211)
Eyal Gerber
  • 1,026
  • 10
  • 27
  • 2
    1. `git diff origin/main` doesn't compare with the remote repository; you need to run `git fetch` first to update the local repo from the remote. 2. There is no need to use `..HEAD`, `git diff origin/main` does exactly the same. 3. There is no need to use `test -z`, `git diff` returns exit code 1 in case of difference so you can do `if git diff -q origin/main; then`. – phd Jun 29 '21 at 15:53
  • 1
    4. If the code detects the script was changed in the `origin` the code could replace the current script with updated using `exec` (with all parameters) after `cd $ORIGINAL_DIRECTORY` thus achieving what you asked from the start — update the script **automatically**. – phd Jun 29 '21 at 16:04
  • @phd thanks for your first comment. You are right that I forgot to write fetch. I will update my answer. Could you elaborate on your second comment? I couldn't find any examples for using exec for the purpose you mentioned. Thanks – Eyal Gerber Jun 30 '21 at 09:04
  • 1
    @phd after some testing I found that there is a slight difference between adding the `..HEAD` to the diff command and not using it. The main difference is that if you DO include the `..HEAD` then it will compare with the current checkout head and not with any uncommitted changes you have. This is important because as I am making changes and tests to the scripts I want to be able to run them. If I remove the `..HEAD` then I keep failing the condition and am unable to run the scripts prior to committing them. So for me, I am going to keep the `..HEAD` in the script. – Eyal Gerber Jun 30 '21 at 09:26
  • `exec` in shell means "replace the current process with a new one". Thus after updating the script on disk `exec $0 $@` replaces the current script with a new code from the repository. – phd Jun 30 '21 at 09:59