'git clone and cd into it

If I wanted to make a directory and change directory into it all in one line, I could do something like this:

mkdir dir_name && cd $_

How can I do the same with git clone?

The command, git clone repo_url && cd $_, won't work obviously, because there's no such directory as repo_url. But is it possible to do it in one line?



Solution 1:[1]

If you want to find the name automatically you could try something like that:

git clone http://repo_url.git && cd "$(basename "$_" .git)"

That way you don't have to specify a folder name to git.

Solution 2:[2]

You can add a directory name for the git clone command:

git clone repo_url my_repo_dirname && cd "$_"

Solution 3:[3]

You can use the following

git clone http://repo_url.git && cd "!$:t:r"

Imp: Do not forget the double quotes in the cd command, else it won't work in some other shells or Git Bash in Windows.

How does it work?

The first command is the obvious git clone command. The second cd command is intriguing.

Now there is something called Word Designators for command history

  • !$ is the last part of the last command run

Here the last command run would be git clone http://repo_url.git. This command consists of three parts. 1. git, 2. clone and 3. http://repo_url.git. And http://repo_url.git is the last part. Hence !$ ==> http://repo_url.git

Then there is something called Word Modifiers, which modify the string preceding it.

  • :t removes all leading file name components, leaving the tail

So here !$:t would be read like (!$):t. Hence !$:t ==> repo_url.git

  • :r removes the trailing suffix from filenames like abcd.xyz, leaving abcd

So here !$:t:r would be read like {(!$):t}:r. Hence !$:t:r ==> repo_url

So it would cd to repo_url

To debug this yourself, use :p which just prints the command preceding it without executing it. Equivalent would be echo

Run the following in the exact sequence

  1. git clone http://repo_url.git
  2. !$:p ==> http://repo_url.git (or echo !$)
  3. !$:t:p ==> repo_url.git (or echo !$:t)
  4. !$:t:r:p ==> repo_url (or echo !$:t:r)

Solution 4:[4]

Add the following to your ~/.bashrc. Don't forget to source it!

function gccd { git clone "$1" && cd "$(basename $1 .git)"; }
export -f gccd

gccd stands for git clone and cd. This is the function equivalent of an alias. Now you can type: gccd <repo>. It will do exactly what you want.

Updated so that it works with both URL and with trailing .git. Thanks @kost

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 chepner
Solution 2 chepner
Solution 3
Solution 4