If you’re like me, you probably work with multiple code repositories. I have around 15 repositories that I might need to access on any given day and about that many more that could be accessed less frequently. Keeping a clean development environment with all of these repositories can be a challenge. Managing the clones of repositories you are actively working on is one thing. But, when adding on all the ad-hoc clones made for short impromptu review or discussions with team members, the housecleaning effort is compounded. In this post, I’ll share a simple bash function to quickly clone a repository for temporary usage and automatically clean it up for you.

First, here are some of the problems I needed to solve.

  • Too Many Git Urls With so many repositories, remembering all the git urls is difficult. When I need to clone a repository, I normally go to BitBucket, navigate to the project and repository, and copy the clone url. This is extra time used when I just need quick access to the code. Even if I remembered it, having to type in the full url doesn’t save much time.
  • Organizational Decisions On my local system, I have to decide where to put the clone and navigate to that directory. That doesn’t sound too difficult, but it is just one more thing to think about while trying to keep an organized environment.
  • CLEAN UP This is the biggest problem. When I’m finished with the clone (I may have only needed it for a few minutes), I should remove it. But, for some reason, that rarely happens. A conversation with a team member might continue after looking at the code and I forget. I might think I’ll need it again soon and don’t want to go back through the cloning steps mentioned above. Or, i just move on to the next task and don’t even think about it.

As you can imagine, this can result in a cluttered environment and brings with it additional problems. In the next weeks or months, I might decide to do some housekeeping and these questions arise. Why do I have that clone? Was I working on something there? Are there any commits, are they pushed, do they need to be? If I delete this, what am I going to lose? All this because I needed to clone a repository for only a few minutes.

My solution to this is a quick clone bash function that fixes all of the problems above in one simple command qcl [project name].

The first step is to create a local file containing all the git urls with an associated project name. It’s a simple text file with the project name, space, and the git url.

awesome file:///home/Doug/tmp/.repos/awesome/.git/
project file:///home/Doug/tmp/.repos/project/.git/

Here is the function. It should be self explanatory. It basically pulls the git url from the file based on the project name given. Navigates to a temporary directory and creates the clone. It then opens VI to allow you to view the code. Once you close VI, the clone is removed. That’s it. Quick, simple, and no mess left over.

qcl() {

    # Validate arguments
    if [ "${1}X" == "X" ]
    then
        echo "Project namem must be given as an argument";
    fi
        
    # The temp directory for the clone
    TMP=~/tmp
   
    # The project name as argument 1
    PROJECT=`echo ${1} | sed 's/ /_/g'`
    
    # The directory for the clone
    PROJECTTMP=${TMP}/${PROJECT}
   
    # Where to return to
    PPWD=`pwd`
    
    # Get the url from the repo file by name
    GITURL=`grep "^${PROJECT} " ~/.repos | awk '{print $2}'`

    # Some validation
    if [ ! -d ${TMP} ]
    then
        echo "TMP directory does not exist: ${TMP}"
        return 1
    fi

    if [ -d ${PROJECTTMP} ]
    then
        echo "Project directory already exist: ${PROJECT}"
        return 1
    fi

    if [ "${GITURL}X" == "X" ]
    then
        echo "Repository not found for ${PROJECT}"
        return 1
    fi

    echo "Quick clone to ${PROJECTTMP}"
    echo

    # Clone the repo
    cd $TMP

    git clone ${GITURL} ${PROJECT}
    cd $PROJECTTMP
    
    # View the code, ,n opens NerdTree 
    vi -c 'execute "normal ,n"'
    
    # Clean up
    cd $PPWD
    rm -rf ${PROJECTTMP}

    echo "Quick clone cleaned up"
    echo

}

Now, to take it one step further and make it dead simple to quickly clone a repository, I added autocompletion to the function. I have written a previous post on autocompletion here Autocomplete Anything in Bash.

To enable autocompletion, add this to the file with the qcl function above.

_repo_list() {
    local cur
    local repoFile
    repoFile=~/.repos

    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
                    
    COMPREPLY=( $(cat  ${repoFile} | awk '{print $1}' | grep "^${cur}.*") )
}

complete -F _repo_list qcl

That’s it. Here is the function in action.

Quick Clone Demo

Quick Clone Demo

I’d love to hear how you’ve addressed these issues or other tricks you use to maintain a clean and productive environment. Please share in the comments.

Share this on: