How to cd automatically after git clone?












30















I want to automatically cd to the directory created by the clone command after I git cloned something.



Important: I don't want to alter the syntax for the command (e.g. use an alias/function) because it would break the zsh-completions I get automatically from the Pretzo project.



EDIT: The reason I didn't pick any answer as correct, is because no answer was given that did comply with the condition above.



I use ZSH, but an answer in any other shell is acceptable as well.










share|improve this question

























  • I like the answer unix.stackexchange.com/questions/97920/… but it need to mention to write that function on ~/.bashrc file (for example) and for me at least it didn't work, I needed to fix it with the replacing the line : /usr/bin/git "$@" 2>&1 | tee $tmp

    – lcestari
    Jan 6 '15 at 19:12
















30















I want to automatically cd to the directory created by the clone command after I git cloned something.



Important: I don't want to alter the syntax for the command (e.g. use an alias/function) because it would break the zsh-completions I get automatically from the Pretzo project.



EDIT: The reason I didn't pick any answer as correct, is because no answer was given that did comply with the condition above.



I use ZSH, but an answer in any other shell is acceptable as well.










share|improve this question

























  • I like the answer unix.stackexchange.com/questions/97920/… but it need to mention to write that function on ~/.bashrc file (for example) and for me at least it didn't work, I needed to fix it with the replacing the line : /usr/bin/git "$@" 2>&1 | tee $tmp

    – lcestari
    Jan 6 '15 at 19:12














30












30








30


9






I want to automatically cd to the directory created by the clone command after I git cloned something.



Important: I don't want to alter the syntax for the command (e.g. use an alias/function) because it would break the zsh-completions I get automatically from the Pretzo project.



EDIT: The reason I didn't pick any answer as correct, is because no answer was given that did comply with the condition above.



I use ZSH, but an answer in any other shell is acceptable as well.










share|improve this question
















I want to automatically cd to the directory created by the clone command after I git cloned something.



Important: I don't want to alter the syntax for the command (e.g. use an alias/function) because it would break the zsh-completions I get automatically from the Pretzo project.



EDIT: The reason I didn't pick any answer as correct, is because no answer was given that did comply with the condition above.



I use ZSH, but an answer in any other shell is acceptable as well.







shell zsh






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Apr 15 '16 at 2:37









techraf

4,183102139




4,183102139










asked Oct 28 '13 at 14:10









Cat BossCat Boss

4201415




4201415













  • I like the answer unix.stackexchange.com/questions/97920/… but it need to mention to write that function on ~/.bashrc file (for example) and for me at least it didn't work, I needed to fix it with the replacing the line : /usr/bin/git "$@" 2>&1 | tee $tmp

    – lcestari
    Jan 6 '15 at 19:12



















  • I like the answer unix.stackexchange.com/questions/97920/… but it need to mention to write that function on ~/.bashrc file (for example) and for me at least it didn't work, I needed to fix it with the replacing the line : /usr/bin/git "$@" 2>&1 | tee $tmp

    – lcestari
    Jan 6 '15 at 19:12

















I like the answer unix.stackexchange.com/questions/97920/… but it need to mention to write that function on ~/.bashrc file (for example) and for me at least it didn't work, I needed to fix it with the replacing the line : /usr/bin/git "$@" 2>&1 | tee $tmp

– lcestari
Jan 6 '15 at 19:12





I like the answer unix.stackexchange.com/questions/97920/… but it need to mention to write that function on ~/.bashrc file (for example) and for me at least it didn't work, I needed to fix it with the replacing the line : /usr/bin/git "$@" 2>&1 | tee $tmp

– lcestari
Jan 6 '15 at 19:12










8 Answers
8






active

oldest

votes


















17














Create a function:



gclonecd() {
git clone "$1" && cd "$(basename "$1" .git)"
}


(Works for links both with and without ".git")






share|improve this answer





















  • 2





    I would like to keep using git clone because of all the tools that I would have to change if I were not using git. Hub is aliased as git, oh-my-zsh provides auto-completion, etc...

    – Cat Boss
    Oct 28 '13 at 14:44








  • 3





    @Wildeyes git can't change the working directory of your shell, so either way you'll have to wrap it in an alias/function that does what you want and follows it up with the builtin cd. If you want to call hub instead of git, do so in the function. If you want it to only affect the clone command, check for the action in the function. etc.

    – frostschutz
    Oct 28 '13 at 15:04











  • I noticed that basename git@github.com:pckujawa/pattern-rec.git results in pattern-rec.git - do you just leave off the .git extension when you clone?

    – Pat
    Jun 28 '14 at 5:03






  • 8





    @Pat basename also takes a suffix argument, so you can do: git clone $1 && cd $(basename $1 .git)

    – Henrik N
    Nov 13 '15 at 20:40



















15














git clone takes an additional argument: the directory to use. You can make it clone into the current working directory with git clone URL . Then, there is no need to change working directory; you are already there.



If you really want the git command to actually change working directory, you can change it to a function which calls the real git when necessary:



git()
{
local tmp=$(mktemp)
local repo_name

if [ "$1" = clone ] ; then
/usr/bin/git "$@" | tee $tmp
repo_name=$(awk -F' '/Cloning into/ {print $2}' $tmp)
rm $tmp
printf "changing to directory %sn" "$repo_name"
cd "$repo_name"
else
/usr/bin/git "$@"
fi
}





share|improve this answer


























  • That was exactly what I was looking for. After I realized there are no internal hooks or something like that, I wrote an almost exact function :)

    – Cat Boss
    Oct 28 '13 at 19:38











  • If I may, why write the output of git to a file and then read it and then extract the name... if you could simply name="$(basename $3), remove the extension and cd to that?

    – Cat Boss
    Oct 28 '13 at 19:40






  • 2





    @Wildeyes Yes: have a /tmp volume which is in RAM, like any modern Linux does via tmpfs. Anyway, why would you care about writing to the disk, when you've just done a git clone, which creates directories and writes perhaps hundreds of files to the disk ...

    – Kaz
    Oct 29 '13 at 19:02








  • 1





    You're probably right about the whole "nvm if it writes to disk" thing, I was just looking to save extra operations. Thanks a lot Kaz.

    – Cat Boss
    Oct 29 '13 at 19:24






  • 2





    Be careful. it is git [flags] command [arguments], so blindly asking for clone in certain position will fail.

    – vonbrand
    Feb 13 '16 at 22:19



















7














If you provide the local name of the repo, it's really easy using $_:



git clone git@github.com:npm/npm.git npm-local-dir && cd $_


But if you don't want to re-type long names, it's a little ugly but doable with sed:



git clone git@github.com:pckujawa/pattern-rec.git && 
cd `echo $_ | sed -n -e 's/^.*/([^.]*)(.git)*/1/p'`


EDIT: Well, I was going to thank Manav (comment below) for the terse



git clone foo/bar && cd !$:t


but it doesn't work in zsh (something about how zsh does expansions causes it not to treat the first command as input to !$). I had to look up what !$:t did (Advancing in the Bash Shell | ${me:-whatever}). !$ grabs the last part of the previous command and :t will "Remove all leading file name components, leaving the tail." Good information, but I wish I could get it to work with zsh (I tried noglob with no success).



EDIT: Instead of using sed or !$:t (which doesn't work in zsh, for me anyway), I found two other options (one adapting https://unix.stackexchange.com/users/5685/frederik-deweerdt 's answer with https://unix.stackexchange.com/users/129926/henrik-n 's comment):



git clone git@github.com:npm/npm.git && cd $(basename $_ .git)


or



git clone git@github.com:npm/npm.git && cd ${${_%%.git*}##*/}





share|improve this answer


























  • git clone foo/bar && cd !$:t

    – Manav
    Mar 21 '15 at 6:52











  • If your repo url ends in .git you can use !$:t:r to get the folder name.

    – Michael Stramel
    Jan 30 '18 at 16:36





















2














Here is an adaptation of the above answer for OSX





  • mktemp requires additional parameter


  • git clone writes to STDERR by default (see this)


Function:



function git {
local tmp=$(mktemp -t git)
local repo_name

if [ "$1" = clone ] ; then
command git "$@" --progress 2>&1 | tee $tmp
repo_name=$(awk -F' '/Cloning into/ {print $2}' $tmp)
rm $tmp
printf "changing to directory %sn" "$repo_name"
cd "$repo_name"
else
command git "$@"
fi
}





share|improve this answer





















  • 1





    There are 7 answers that display "above" yours. But it may change over time. Such references make no sense on SE, please edit your answer and include a link to the answer you were referring to.

    – techraf
    Apr 15 '16 at 2:40



















1














A simple solution for any POSIX shell is to specify the directory to clone to explicitly (any filesystem path) and reuse it:



git clone <repository> <directory> &&
cd "$_"


and



cd -


when you're done.






share|improve this answer































    0














    I wouldn't recommend it, but you could use this one-liner:



    echo 'project' | xargs -I % sh -c 'git clone https://github.com/username/%.git && cd %'






    share|improve this answer































      0














      You could do something like:



      clone_check() {
      (($? != 0)) && return
      local cmd=$history[$((HISTCMD-1))]
      cmd=("${(@Q)${(z)cmd}}")
      if [[ $cmd = "git clone "* ]]; then
      local dir
      if (($#cmd == 3)); then
      dir=${cmd[3]:t}
      dir=${dir%.git}
      dir=${dir#*:}
      elif (($#cmd > 3)); then
      dir=$cmd[-1]
      else
      return
      fi
      print -r CDing into $dir > /dev/tty
      cd -- $dir
      fi
      }
      precmd_functions+=(clone_check)


      It is quite simplistic. It's a precmd hook (executed before each prompt), that checks whether the last command line looked like git clone .../something or git clone .../something dir, guess the directory from that and cd into it.



      It doesn't work if you entered git clone foo; whatever or whatever; git clone foo or git clone --option repo...






      share|improve this answer

































        0














        Include this in your shell:



        git(){
        case "$1" in clone) git-clone "${@:2}";; *) command git "$@";; esac
        }
        git-clone(){
        local tgt
        tgt=$(command git clone "$@" 2> >(tee /dev/stderr |head -n1 | cut -d ' -f2)) ||
        return $?
        cd "$tgt"
        }


        This works by surreptisiously gleaning the cloning target from git's standard error and cd'ing into the target if (and only if) the cloning was a success.



        It accepts all arguments and options that the regular git clone does.



        Either you can use the git wrapper and not have to worry about your completions, or you can get rid of the git wrapper and rewire your git clone completions to git-clone.






        share|improve this answer

























          Your Answer








          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "106"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f97920%2fhow-to-cd-automatically-after-git-clone%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          8 Answers
          8






          active

          oldest

          votes








          8 Answers
          8






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          17














          Create a function:



          gclonecd() {
          git clone "$1" && cd "$(basename "$1" .git)"
          }


          (Works for links both with and without ".git")






          share|improve this answer





















          • 2





            I would like to keep using git clone because of all the tools that I would have to change if I were not using git. Hub is aliased as git, oh-my-zsh provides auto-completion, etc...

            – Cat Boss
            Oct 28 '13 at 14:44








          • 3





            @Wildeyes git can't change the working directory of your shell, so either way you'll have to wrap it in an alias/function that does what you want and follows it up with the builtin cd. If you want to call hub instead of git, do so in the function. If you want it to only affect the clone command, check for the action in the function. etc.

            – frostschutz
            Oct 28 '13 at 15:04











          • I noticed that basename git@github.com:pckujawa/pattern-rec.git results in pattern-rec.git - do you just leave off the .git extension when you clone?

            – Pat
            Jun 28 '14 at 5:03






          • 8





            @Pat basename also takes a suffix argument, so you can do: git clone $1 && cd $(basename $1 .git)

            – Henrik N
            Nov 13 '15 at 20:40
















          17














          Create a function:



          gclonecd() {
          git clone "$1" && cd "$(basename "$1" .git)"
          }


          (Works for links both with and without ".git")






          share|improve this answer





















          • 2





            I would like to keep using git clone because of all the tools that I would have to change if I were not using git. Hub is aliased as git, oh-my-zsh provides auto-completion, etc...

            – Cat Boss
            Oct 28 '13 at 14:44








          • 3





            @Wildeyes git can't change the working directory of your shell, so either way you'll have to wrap it in an alias/function that does what you want and follows it up with the builtin cd. If you want to call hub instead of git, do so in the function. If you want it to only affect the clone command, check for the action in the function. etc.

            – frostschutz
            Oct 28 '13 at 15:04











          • I noticed that basename git@github.com:pckujawa/pattern-rec.git results in pattern-rec.git - do you just leave off the .git extension when you clone?

            – Pat
            Jun 28 '14 at 5:03






          • 8





            @Pat basename also takes a suffix argument, so you can do: git clone $1 && cd $(basename $1 .git)

            – Henrik N
            Nov 13 '15 at 20:40














          17












          17








          17







          Create a function:



          gclonecd() {
          git clone "$1" && cd "$(basename "$1" .git)"
          }


          (Works for links both with and without ".git")






          share|improve this answer















          Create a function:



          gclonecd() {
          git clone "$1" && cd "$(basename "$1" .git)"
          }


          (Works for links both with and without ".git")







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Jan 14 at 12:19









          aksh1618

          9111




          9111










          answered Oct 28 '13 at 14:21









          Frederik DeweerdtFrederik Deweerdt

          3,0021116




          3,0021116








          • 2





            I would like to keep using git clone because of all the tools that I would have to change if I were not using git. Hub is aliased as git, oh-my-zsh provides auto-completion, etc...

            – Cat Boss
            Oct 28 '13 at 14:44








          • 3





            @Wildeyes git can't change the working directory of your shell, so either way you'll have to wrap it in an alias/function that does what you want and follows it up with the builtin cd. If you want to call hub instead of git, do so in the function. If you want it to only affect the clone command, check for the action in the function. etc.

            – frostschutz
            Oct 28 '13 at 15:04











          • I noticed that basename git@github.com:pckujawa/pattern-rec.git results in pattern-rec.git - do you just leave off the .git extension when you clone?

            – Pat
            Jun 28 '14 at 5:03






          • 8





            @Pat basename also takes a suffix argument, so you can do: git clone $1 && cd $(basename $1 .git)

            – Henrik N
            Nov 13 '15 at 20:40














          • 2





            I would like to keep using git clone because of all the tools that I would have to change if I were not using git. Hub is aliased as git, oh-my-zsh provides auto-completion, etc...

            – Cat Boss
            Oct 28 '13 at 14:44








          • 3





            @Wildeyes git can't change the working directory of your shell, so either way you'll have to wrap it in an alias/function that does what you want and follows it up with the builtin cd. If you want to call hub instead of git, do so in the function. If you want it to only affect the clone command, check for the action in the function. etc.

            – frostschutz
            Oct 28 '13 at 15:04











          • I noticed that basename git@github.com:pckujawa/pattern-rec.git results in pattern-rec.git - do you just leave off the .git extension when you clone?

            – Pat
            Jun 28 '14 at 5:03






          • 8





            @Pat basename also takes a suffix argument, so you can do: git clone $1 && cd $(basename $1 .git)

            – Henrik N
            Nov 13 '15 at 20:40








          2




          2





          I would like to keep using git clone because of all the tools that I would have to change if I were not using git. Hub is aliased as git, oh-my-zsh provides auto-completion, etc...

          – Cat Boss
          Oct 28 '13 at 14:44







          I would like to keep using git clone because of all the tools that I would have to change if I were not using git. Hub is aliased as git, oh-my-zsh provides auto-completion, etc...

          – Cat Boss
          Oct 28 '13 at 14:44






          3




          3





          @Wildeyes git can't change the working directory of your shell, so either way you'll have to wrap it in an alias/function that does what you want and follows it up with the builtin cd. If you want to call hub instead of git, do so in the function. If you want it to only affect the clone command, check for the action in the function. etc.

          – frostschutz
          Oct 28 '13 at 15:04





          @Wildeyes git can't change the working directory of your shell, so either way you'll have to wrap it in an alias/function that does what you want and follows it up with the builtin cd. If you want to call hub instead of git, do so in the function. If you want it to only affect the clone command, check for the action in the function. etc.

          – frostschutz
          Oct 28 '13 at 15:04













          I noticed that basename git@github.com:pckujawa/pattern-rec.git results in pattern-rec.git - do you just leave off the .git extension when you clone?

          – Pat
          Jun 28 '14 at 5:03





          I noticed that basename git@github.com:pckujawa/pattern-rec.git results in pattern-rec.git - do you just leave off the .git extension when you clone?

          – Pat
          Jun 28 '14 at 5:03




          8




          8





          @Pat basename also takes a suffix argument, so you can do: git clone $1 && cd $(basename $1 .git)

          – Henrik N
          Nov 13 '15 at 20:40





          @Pat basename also takes a suffix argument, so you can do: git clone $1 && cd $(basename $1 .git)

          – Henrik N
          Nov 13 '15 at 20:40













          15














          git clone takes an additional argument: the directory to use. You can make it clone into the current working directory with git clone URL . Then, there is no need to change working directory; you are already there.



          If you really want the git command to actually change working directory, you can change it to a function which calls the real git when necessary:



          git()
          {
          local tmp=$(mktemp)
          local repo_name

          if [ "$1" = clone ] ; then
          /usr/bin/git "$@" | tee $tmp
          repo_name=$(awk -F' '/Cloning into/ {print $2}' $tmp)
          rm $tmp
          printf "changing to directory %sn" "$repo_name"
          cd "$repo_name"
          else
          /usr/bin/git "$@"
          fi
          }





          share|improve this answer


























          • That was exactly what I was looking for. After I realized there are no internal hooks or something like that, I wrote an almost exact function :)

            – Cat Boss
            Oct 28 '13 at 19:38











          • If I may, why write the output of git to a file and then read it and then extract the name... if you could simply name="$(basename $3), remove the extension and cd to that?

            – Cat Boss
            Oct 28 '13 at 19:40






          • 2





            @Wildeyes Yes: have a /tmp volume which is in RAM, like any modern Linux does via tmpfs. Anyway, why would you care about writing to the disk, when you've just done a git clone, which creates directories and writes perhaps hundreds of files to the disk ...

            – Kaz
            Oct 29 '13 at 19:02








          • 1





            You're probably right about the whole "nvm if it writes to disk" thing, I was just looking to save extra operations. Thanks a lot Kaz.

            – Cat Boss
            Oct 29 '13 at 19:24






          • 2





            Be careful. it is git [flags] command [arguments], so blindly asking for clone in certain position will fail.

            – vonbrand
            Feb 13 '16 at 22:19
















          15














          git clone takes an additional argument: the directory to use. You can make it clone into the current working directory with git clone URL . Then, there is no need to change working directory; you are already there.



          If you really want the git command to actually change working directory, you can change it to a function which calls the real git when necessary:



          git()
          {
          local tmp=$(mktemp)
          local repo_name

          if [ "$1" = clone ] ; then
          /usr/bin/git "$@" | tee $tmp
          repo_name=$(awk -F' '/Cloning into/ {print $2}' $tmp)
          rm $tmp
          printf "changing to directory %sn" "$repo_name"
          cd "$repo_name"
          else
          /usr/bin/git "$@"
          fi
          }





          share|improve this answer


























          • That was exactly what I was looking for. After I realized there are no internal hooks or something like that, I wrote an almost exact function :)

            – Cat Boss
            Oct 28 '13 at 19:38











          • If I may, why write the output of git to a file and then read it and then extract the name... if you could simply name="$(basename $3), remove the extension and cd to that?

            – Cat Boss
            Oct 28 '13 at 19:40






          • 2





            @Wildeyes Yes: have a /tmp volume which is in RAM, like any modern Linux does via tmpfs. Anyway, why would you care about writing to the disk, when you've just done a git clone, which creates directories and writes perhaps hundreds of files to the disk ...

            – Kaz
            Oct 29 '13 at 19:02








          • 1





            You're probably right about the whole "nvm if it writes to disk" thing, I was just looking to save extra operations. Thanks a lot Kaz.

            – Cat Boss
            Oct 29 '13 at 19:24






          • 2





            Be careful. it is git [flags] command [arguments], so blindly asking for clone in certain position will fail.

            – vonbrand
            Feb 13 '16 at 22:19














          15












          15








          15







          git clone takes an additional argument: the directory to use. You can make it clone into the current working directory with git clone URL . Then, there is no need to change working directory; you are already there.



          If you really want the git command to actually change working directory, you can change it to a function which calls the real git when necessary:



          git()
          {
          local tmp=$(mktemp)
          local repo_name

          if [ "$1" = clone ] ; then
          /usr/bin/git "$@" | tee $tmp
          repo_name=$(awk -F' '/Cloning into/ {print $2}' $tmp)
          rm $tmp
          printf "changing to directory %sn" "$repo_name"
          cd "$repo_name"
          else
          /usr/bin/git "$@"
          fi
          }





          share|improve this answer















          git clone takes an additional argument: the directory to use. You can make it clone into the current working directory with git clone URL . Then, there is no need to change working directory; you are already there.



          If you really want the git command to actually change working directory, you can change it to a function which calls the real git when necessary:



          git()
          {
          local tmp=$(mktemp)
          local repo_name

          if [ "$1" = clone ] ; then
          /usr/bin/git "$@" | tee $tmp
          repo_name=$(awk -F' '/Cloning into/ {print $2}' $tmp)
          rm $tmp
          printf "changing to directory %sn" "$repo_name"
          cd "$repo_name"
          else
          /usr/bin/git "$@"
          fi
          }






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Oct 28 '13 at 18:39

























          answered Oct 28 '13 at 18:20









          KazKaz

          4,59311432




          4,59311432













          • That was exactly what I was looking for. After I realized there are no internal hooks or something like that, I wrote an almost exact function :)

            – Cat Boss
            Oct 28 '13 at 19:38











          • If I may, why write the output of git to a file and then read it and then extract the name... if you could simply name="$(basename $3), remove the extension and cd to that?

            – Cat Boss
            Oct 28 '13 at 19:40






          • 2





            @Wildeyes Yes: have a /tmp volume which is in RAM, like any modern Linux does via tmpfs. Anyway, why would you care about writing to the disk, when you've just done a git clone, which creates directories and writes perhaps hundreds of files to the disk ...

            – Kaz
            Oct 29 '13 at 19:02








          • 1





            You're probably right about the whole "nvm if it writes to disk" thing, I was just looking to save extra operations. Thanks a lot Kaz.

            – Cat Boss
            Oct 29 '13 at 19:24






          • 2





            Be careful. it is git [flags] command [arguments], so blindly asking for clone in certain position will fail.

            – vonbrand
            Feb 13 '16 at 22:19



















          • That was exactly what I was looking for. After I realized there are no internal hooks or something like that, I wrote an almost exact function :)

            – Cat Boss
            Oct 28 '13 at 19:38











          • If I may, why write the output of git to a file and then read it and then extract the name... if you could simply name="$(basename $3), remove the extension and cd to that?

            – Cat Boss
            Oct 28 '13 at 19:40






          • 2





            @Wildeyes Yes: have a /tmp volume which is in RAM, like any modern Linux does via tmpfs. Anyway, why would you care about writing to the disk, when you've just done a git clone, which creates directories and writes perhaps hundreds of files to the disk ...

            – Kaz
            Oct 29 '13 at 19:02








          • 1





            You're probably right about the whole "nvm if it writes to disk" thing, I was just looking to save extra operations. Thanks a lot Kaz.

            – Cat Boss
            Oct 29 '13 at 19:24






          • 2





            Be careful. it is git [flags] command [arguments], so blindly asking for clone in certain position will fail.

            – vonbrand
            Feb 13 '16 at 22:19

















          That was exactly what I was looking for. After I realized there are no internal hooks or something like that, I wrote an almost exact function :)

          – Cat Boss
          Oct 28 '13 at 19:38





          That was exactly what I was looking for. After I realized there are no internal hooks or something like that, I wrote an almost exact function :)

          – Cat Boss
          Oct 28 '13 at 19:38













          If I may, why write the output of git to a file and then read it and then extract the name... if you could simply name="$(basename $3), remove the extension and cd to that?

          – Cat Boss
          Oct 28 '13 at 19:40





          If I may, why write the output of git to a file and then read it and then extract the name... if you could simply name="$(basename $3), remove the extension and cd to that?

          – Cat Boss
          Oct 28 '13 at 19:40




          2




          2





          @Wildeyes Yes: have a /tmp volume which is in RAM, like any modern Linux does via tmpfs. Anyway, why would you care about writing to the disk, when you've just done a git clone, which creates directories and writes perhaps hundreds of files to the disk ...

          – Kaz
          Oct 29 '13 at 19:02







          @Wildeyes Yes: have a /tmp volume which is in RAM, like any modern Linux does via tmpfs. Anyway, why would you care about writing to the disk, when you've just done a git clone, which creates directories and writes perhaps hundreds of files to the disk ...

          – Kaz
          Oct 29 '13 at 19:02






          1




          1





          You're probably right about the whole "nvm if it writes to disk" thing, I was just looking to save extra operations. Thanks a lot Kaz.

          – Cat Boss
          Oct 29 '13 at 19:24





          You're probably right about the whole "nvm if it writes to disk" thing, I was just looking to save extra operations. Thanks a lot Kaz.

          – Cat Boss
          Oct 29 '13 at 19:24




          2




          2





          Be careful. it is git [flags] command [arguments], so blindly asking for clone in certain position will fail.

          – vonbrand
          Feb 13 '16 at 22:19





          Be careful. it is git [flags] command [arguments], so blindly asking for clone in certain position will fail.

          – vonbrand
          Feb 13 '16 at 22:19











          7














          If you provide the local name of the repo, it's really easy using $_:



          git clone git@github.com:npm/npm.git npm-local-dir && cd $_


          But if you don't want to re-type long names, it's a little ugly but doable with sed:



          git clone git@github.com:pckujawa/pattern-rec.git && 
          cd `echo $_ | sed -n -e 's/^.*/([^.]*)(.git)*/1/p'`


          EDIT: Well, I was going to thank Manav (comment below) for the terse



          git clone foo/bar && cd !$:t


          but it doesn't work in zsh (something about how zsh does expansions causes it not to treat the first command as input to !$). I had to look up what !$:t did (Advancing in the Bash Shell | ${me:-whatever}). !$ grabs the last part of the previous command and :t will "Remove all leading file name components, leaving the tail." Good information, but I wish I could get it to work with zsh (I tried noglob with no success).



          EDIT: Instead of using sed or !$:t (which doesn't work in zsh, for me anyway), I found two other options (one adapting https://unix.stackexchange.com/users/5685/frederik-deweerdt 's answer with https://unix.stackexchange.com/users/129926/henrik-n 's comment):



          git clone git@github.com:npm/npm.git && cd $(basename $_ .git)


          or



          git clone git@github.com:npm/npm.git && cd ${${_%%.git*}##*/}





          share|improve this answer


























          • git clone foo/bar && cd !$:t

            – Manav
            Mar 21 '15 at 6:52











          • If your repo url ends in .git you can use !$:t:r to get the folder name.

            – Michael Stramel
            Jan 30 '18 at 16:36


















          7














          If you provide the local name of the repo, it's really easy using $_:



          git clone git@github.com:npm/npm.git npm-local-dir && cd $_


          But if you don't want to re-type long names, it's a little ugly but doable with sed:



          git clone git@github.com:pckujawa/pattern-rec.git && 
          cd `echo $_ | sed -n -e 's/^.*/([^.]*)(.git)*/1/p'`


          EDIT: Well, I was going to thank Manav (comment below) for the terse



          git clone foo/bar && cd !$:t


          but it doesn't work in zsh (something about how zsh does expansions causes it not to treat the first command as input to !$). I had to look up what !$:t did (Advancing in the Bash Shell | ${me:-whatever}). !$ grabs the last part of the previous command and :t will "Remove all leading file name components, leaving the tail." Good information, but I wish I could get it to work with zsh (I tried noglob with no success).



          EDIT: Instead of using sed or !$:t (which doesn't work in zsh, for me anyway), I found two other options (one adapting https://unix.stackexchange.com/users/5685/frederik-deweerdt 's answer with https://unix.stackexchange.com/users/129926/henrik-n 's comment):



          git clone git@github.com:npm/npm.git && cd $(basename $_ .git)


          or



          git clone git@github.com:npm/npm.git && cd ${${_%%.git*}##*/}





          share|improve this answer


























          • git clone foo/bar && cd !$:t

            – Manav
            Mar 21 '15 at 6:52











          • If your repo url ends in .git you can use !$:t:r to get the folder name.

            – Michael Stramel
            Jan 30 '18 at 16:36
















          7












          7








          7







          If you provide the local name of the repo, it's really easy using $_:



          git clone git@github.com:npm/npm.git npm-local-dir && cd $_


          But if you don't want to re-type long names, it's a little ugly but doable with sed:



          git clone git@github.com:pckujawa/pattern-rec.git && 
          cd `echo $_ | sed -n -e 's/^.*/([^.]*)(.git)*/1/p'`


          EDIT: Well, I was going to thank Manav (comment below) for the terse



          git clone foo/bar && cd !$:t


          but it doesn't work in zsh (something about how zsh does expansions causes it not to treat the first command as input to !$). I had to look up what !$:t did (Advancing in the Bash Shell | ${me:-whatever}). !$ grabs the last part of the previous command and :t will "Remove all leading file name components, leaving the tail." Good information, but I wish I could get it to work with zsh (I tried noglob with no success).



          EDIT: Instead of using sed or !$:t (which doesn't work in zsh, for me anyway), I found two other options (one adapting https://unix.stackexchange.com/users/5685/frederik-deweerdt 's answer with https://unix.stackexchange.com/users/129926/henrik-n 's comment):



          git clone git@github.com:npm/npm.git && cd $(basename $_ .git)


          or



          git clone git@github.com:npm/npm.git && cd ${${_%%.git*}##*/}





          share|improve this answer















          If you provide the local name of the repo, it's really easy using $_:



          git clone git@github.com:npm/npm.git npm-local-dir && cd $_


          But if you don't want to re-type long names, it's a little ugly but doable with sed:



          git clone git@github.com:pckujawa/pattern-rec.git && 
          cd `echo $_ | sed -n -e 's/^.*/([^.]*)(.git)*/1/p'`


          EDIT: Well, I was going to thank Manav (comment below) for the terse



          git clone foo/bar && cd !$:t


          but it doesn't work in zsh (something about how zsh does expansions causes it not to treat the first command as input to !$). I had to look up what !$:t did (Advancing in the Bash Shell | ${me:-whatever}). !$ grabs the last part of the previous command and :t will "Remove all leading file name components, leaving the tail." Good information, but I wish I could get it to work with zsh (I tried noglob with no success).



          EDIT: Instead of using sed or !$:t (which doesn't work in zsh, for me anyway), I found two other options (one adapting https://unix.stackexchange.com/users/5685/frederik-deweerdt 's answer with https://unix.stackexchange.com/users/129926/henrik-n 's comment):



          git clone git@github.com:npm/npm.git && cd $(basename $_ .git)


          or



          git clone git@github.com:npm/npm.git && cd ${${_%%.git*}##*/}






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Dec 24 '17 at 0:02









          Community

          1




          1










          answered Jun 27 '14 at 23:46









          PatPat

          42956




          42956













          • git clone foo/bar && cd !$:t

            – Manav
            Mar 21 '15 at 6:52











          • If your repo url ends in .git you can use !$:t:r to get the folder name.

            – Michael Stramel
            Jan 30 '18 at 16:36





















          • git clone foo/bar && cd !$:t

            – Manav
            Mar 21 '15 at 6:52











          • If your repo url ends in .git you can use !$:t:r to get the folder name.

            – Michael Stramel
            Jan 30 '18 at 16:36



















          git clone foo/bar && cd !$:t

          – Manav
          Mar 21 '15 at 6:52





          git clone foo/bar && cd !$:t

          – Manav
          Mar 21 '15 at 6:52













          If your repo url ends in .git you can use !$:t:r to get the folder name.

          – Michael Stramel
          Jan 30 '18 at 16:36







          If your repo url ends in .git you can use !$:t:r to get the folder name.

          – Michael Stramel
          Jan 30 '18 at 16:36













          2














          Here is an adaptation of the above answer for OSX





          • mktemp requires additional parameter


          • git clone writes to STDERR by default (see this)


          Function:



          function git {
          local tmp=$(mktemp -t git)
          local repo_name

          if [ "$1" = clone ] ; then
          command git "$@" --progress 2>&1 | tee $tmp
          repo_name=$(awk -F' '/Cloning into/ {print $2}' $tmp)
          rm $tmp
          printf "changing to directory %sn" "$repo_name"
          cd "$repo_name"
          else
          command git "$@"
          fi
          }





          share|improve this answer





















          • 1





            There are 7 answers that display "above" yours. But it may change over time. Such references make no sense on SE, please edit your answer and include a link to the answer you were referring to.

            – techraf
            Apr 15 '16 at 2:40
















          2














          Here is an adaptation of the above answer for OSX





          • mktemp requires additional parameter


          • git clone writes to STDERR by default (see this)


          Function:



          function git {
          local tmp=$(mktemp -t git)
          local repo_name

          if [ "$1" = clone ] ; then
          command git "$@" --progress 2>&1 | tee $tmp
          repo_name=$(awk -F' '/Cloning into/ {print $2}' $tmp)
          rm $tmp
          printf "changing to directory %sn" "$repo_name"
          cd "$repo_name"
          else
          command git "$@"
          fi
          }





          share|improve this answer





















          • 1





            There are 7 answers that display "above" yours. But it may change over time. Such references make no sense on SE, please edit your answer and include a link to the answer you were referring to.

            – techraf
            Apr 15 '16 at 2:40














          2












          2








          2







          Here is an adaptation of the above answer for OSX





          • mktemp requires additional parameter


          • git clone writes to STDERR by default (see this)


          Function:



          function git {
          local tmp=$(mktemp -t git)
          local repo_name

          if [ "$1" = clone ] ; then
          command git "$@" --progress 2>&1 | tee $tmp
          repo_name=$(awk -F' '/Cloning into/ {print $2}' $tmp)
          rm $tmp
          printf "changing to directory %sn" "$repo_name"
          cd "$repo_name"
          else
          command git "$@"
          fi
          }





          share|improve this answer















          Here is an adaptation of the above answer for OSX





          • mktemp requires additional parameter


          • git clone writes to STDERR by default (see this)


          Function:



          function git {
          local tmp=$(mktemp -t git)
          local repo_name

          if [ "$1" = clone ] ; then
          command git "$@" --progress 2>&1 | tee $tmp
          repo_name=$(awk -F' '/Cloning into/ {print $2}' $tmp)
          rm $tmp
          printf "changing to directory %sn" "$repo_name"
          cd "$repo_name"
          else
          command git "$@"
          fi
          }






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited May 23 '17 at 12:39









          Community

          1




          1










          answered Sep 21 '15 at 10:13









          davidhqdavidhq

          1513




          1513








          • 1





            There are 7 answers that display "above" yours. But it may change over time. Such references make no sense on SE, please edit your answer and include a link to the answer you were referring to.

            – techraf
            Apr 15 '16 at 2:40














          • 1





            There are 7 answers that display "above" yours. But it may change over time. Such references make no sense on SE, please edit your answer and include a link to the answer you were referring to.

            – techraf
            Apr 15 '16 at 2:40








          1




          1





          There are 7 answers that display "above" yours. But it may change over time. Such references make no sense on SE, please edit your answer and include a link to the answer you were referring to.

          – techraf
          Apr 15 '16 at 2:40





          There are 7 answers that display "above" yours. But it may change over time. Such references make no sense on SE, please edit your answer and include a link to the answer you were referring to.

          – techraf
          Apr 15 '16 at 2:40











          1














          A simple solution for any POSIX shell is to specify the directory to clone to explicitly (any filesystem path) and reuse it:



          git clone <repository> <directory> &&
          cd "$_"


          and



          cd -


          when you're done.






          share|improve this answer




























            1














            A simple solution for any POSIX shell is to specify the directory to clone to explicitly (any filesystem path) and reuse it:



            git clone <repository> <directory> &&
            cd "$_"


            and



            cd -


            when you're done.






            share|improve this answer


























              1












              1








              1







              A simple solution for any POSIX shell is to specify the directory to clone to explicitly (any filesystem path) and reuse it:



              git clone <repository> <directory> &&
              cd "$_"


              and



              cd -


              when you're done.






              share|improve this answer













              A simple solution for any POSIX shell is to specify the directory to clone to explicitly (any filesystem path) and reuse it:



              git clone <repository> <directory> &&
              cd "$_"


              and



              cd -


              when you're done.







              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Apr 14 '16 at 14:01









              Sander MaijersSander Maijers

              212




              212























                  0














                  I wouldn't recommend it, but you could use this one-liner:



                  echo 'project' | xargs -I % sh -c 'git clone https://github.com/username/%.git && cd %'






                  share|improve this answer




























                    0














                    I wouldn't recommend it, but you could use this one-liner:



                    echo 'project' | xargs -I % sh -c 'git clone https://github.com/username/%.git && cd %'






                    share|improve this answer


























                      0












                      0








                      0







                      I wouldn't recommend it, but you could use this one-liner:



                      echo 'project' | xargs -I % sh -c 'git clone https://github.com/username/%.git && cd %'






                      share|improve this answer













                      I wouldn't recommend it, but you could use this one-liner:



                      echo 'project' | xargs -I % sh -c 'git clone https://github.com/username/%.git && cd %'







                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Sep 25 '14 at 23:22









                      christianbundychristianbundy

                      1011




                      1011























                          0














                          You could do something like:



                          clone_check() {
                          (($? != 0)) && return
                          local cmd=$history[$((HISTCMD-1))]
                          cmd=("${(@Q)${(z)cmd}}")
                          if [[ $cmd = "git clone "* ]]; then
                          local dir
                          if (($#cmd == 3)); then
                          dir=${cmd[3]:t}
                          dir=${dir%.git}
                          dir=${dir#*:}
                          elif (($#cmd > 3)); then
                          dir=$cmd[-1]
                          else
                          return
                          fi
                          print -r CDing into $dir > /dev/tty
                          cd -- $dir
                          fi
                          }
                          precmd_functions+=(clone_check)


                          It is quite simplistic. It's a precmd hook (executed before each prompt), that checks whether the last command line looked like git clone .../something or git clone .../something dir, guess the directory from that and cd into it.



                          It doesn't work if you entered git clone foo; whatever or whatever; git clone foo or git clone --option repo...






                          share|improve this answer






























                            0














                            You could do something like:



                            clone_check() {
                            (($? != 0)) && return
                            local cmd=$history[$((HISTCMD-1))]
                            cmd=("${(@Q)${(z)cmd}}")
                            if [[ $cmd = "git clone "* ]]; then
                            local dir
                            if (($#cmd == 3)); then
                            dir=${cmd[3]:t}
                            dir=${dir%.git}
                            dir=${dir#*:}
                            elif (($#cmd > 3)); then
                            dir=$cmd[-1]
                            else
                            return
                            fi
                            print -r CDing into $dir > /dev/tty
                            cd -- $dir
                            fi
                            }
                            precmd_functions+=(clone_check)


                            It is quite simplistic. It's a precmd hook (executed before each prompt), that checks whether the last command line looked like git clone .../something or git clone .../something dir, guess the directory from that and cd into it.



                            It doesn't work if you entered git clone foo; whatever or whatever; git clone foo or git clone --option repo...






                            share|improve this answer




























                              0












                              0








                              0







                              You could do something like:



                              clone_check() {
                              (($? != 0)) && return
                              local cmd=$history[$((HISTCMD-1))]
                              cmd=("${(@Q)${(z)cmd}}")
                              if [[ $cmd = "git clone "* ]]; then
                              local dir
                              if (($#cmd == 3)); then
                              dir=${cmd[3]:t}
                              dir=${dir%.git}
                              dir=${dir#*:}
                              elif (($#cmd > 3)); then
                              dir=$cmd[-1]
                              else
                              return
                              fi
                              print -r CDing into $dir > /dev/tty
                              cd -- $dir
                              fi
                              }
                              precmd_functions+=(clone_check)


                              It is quite simplistic. It's a precmd hook (executed before each prompt), that checks whether the last command line looked like git clone .../something or git clone .../something dir, guess the directory from that and cd into it.



                              It doesn't work if you entered git clone foo; whatever or whatever; git clone foo or git clone --option repo...






                              share|improve this answer















                              You could do something like:



                              clone_check() {
                              (($? != 0)) && return
                              local cmd=$history[$((HISTCMD-1))]
                              cmd=("${(@Q)${(z)cmd}}")
                              if [[ $cmd = "git clone "* ]]; then
                              local dir
                              if (($#cmd == 3)); then
                              dir=${cmd[3]:t}
                              dir=${dir%.git}
                              dir=${dir#*:}
                              elif (($#cmd > 3)); then
                              dir=$cmd[-1]
                              else
                              return
                              fi
                              print -r CDing into $dir > /dev/tty
                              cd -- $dir
                              fi
                              }
                              precmd_functions+=(clone_check)


                              It is quite simplistic. It's a precmd hook (executed before each prompt), that checks whether the last command line looked like git clone .../something or git clone .../something dir, guess the directory from that and cd into it.



                              It doesn't work if you entered git clone foo; whatever or whatever; git clone foo or git clone --option repo...







                              share|improve this answer














                              share|improve this answer



                              share|improve this answer








                              edited Apr 14 '16 at 14:39

























                              answered Apr 14 '16 at 14:31









                              Stéphane ChazelasStéphane Chazelas

                              301k55565917




                              301k55565917























                                  0














                                  Include this in your shell:



                                  git(){
                                  case "$1" in clone) git-clone "${@:2}";; *) command git "$@";; esac
                                  }
                                  git-clone(){
                                  local tgt
                                  tgt=$(command git clone "$@" 2> >(tee /dev/stderr |head -n1 | cut -d ' -f2)) ||
                                  return $?
                                  cd "$tgt"
                                  }


                                  This works by surreptisiously gleaning the cloning target from git's standard error and cd'ing into the target if (and only if) the cloning was a success.



                                  It accepts all arguments and options that the regular git clone does.



                                  Either you can use the git wrapper and not have to worry about your completions, or you can get rid of the git wrapper and rewire your git clone completions to git-clone.






                                  share|improve this answer






























                                    0














                                    Include this in your shell:



                                    git(){
                                    case "$1" in clone) git-clone "${@:2}";; *) command git "$@";; esac
                                    }
                                    git-clone(){
                                    local tgt
                                    tgt=$(command git clone "$@" 2> >(tee /dev/stderr |head -n1 | cut -d ' -f2)) ||
                                    return $?
                                    cd "$tgt"
                                    }


                                    This works by surreptisiously gleaning the cloning target from git's standard error and cd'ing into the target if (and only if) the cloning was a success.



                                    It accepts all arguments and options that the regular git clone does.



                                    Either you can use the git wrapper and not have to worry about your completions, or you can get rid of the git wrapper and rewire your git clone completions to git-clone.






                                    share|improve this answer




























                                      0












                                      0








                                      0







                                      Include this in your shell:



                                      git(){
                                      case "$1" in clone) git-clone "${@:2}";; *) command git "$@";; esac
                                      }
                                      git-clone(){
                                      local tgt
                                      tgt=$(command git clone "$@" 2> >(tee /dev/stderr |head -n1 | cut -d ' -f2)) ||
                                      return $?
                                      cd "$tgt"
                                      }


                                      This works by surreptisiously gleaning the cloning target from git's standard error and cd'ing into the target if (and only if) the cloning was a success.



                                      It accepts all arguments and options that the regular git clone does.



                                      Either you can use the git wrapper and not have to worry about your completions, or you can get rid of the git wrapper and rewire your git clone completions to git-clone.






                                      share|improve this answer















                                      Include this in your shell:



                                      git(){
                                      case "$1" in clone) git-clone "${@:2}";; *) command git "$@";; esac
                                      }
                                      git-clone(){
                                      local tgt
                                      tgt=$(command git clone "$@" 2> >(tee /dev/stderr |head -n1 | cut -d ' -f2)) ||
                                      return $?
                                      cd "$tgt"
                                      }


                                      This works by surreptisiously gleaning the cloning target from git's standard error and cd'ing into the target if (and only if) the cloning was a success.



                                      It accepts all arguments and options that the regular git clone does.



                                      Either you can use the git wrapper and not have to worry about your completions, or you can get rid of the git wrapper and rewire your git clone completions to git-clone.







                                      share|improve this answer














                                      share|improve this answer



                                      share|improve this answer








                                      edited Apr 14 '16 at 15:04

























                                      answered Apr 14 '16 at 14:48









                                      PSkocikPSkocik

                                      17.8k44995




                                      17.8k44995






























                                          draft saved

                                          draft discarded




















































                                          Thanks for contributing an answer to Unix & Linux Stack Exchange!


                                          • Please be sure to answer the question. Provide details and share your research!

                                          But avoid



                                          • Asking for help, clarification, or responding to other answers.

                                          • Making statements based on opinion; back them up with references or personal experience.


                                          To learn more, see our tips on writing great answers.




                                          draft saved


                                          draft discarded














                                          StackExchange.ready(
                                          function () {
                                          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f97920%2fhow-to-cd-automatically-after-git-clone%23new-answer', 'question_page');
                                          }
                                          );

                                          Post as a guest















                                          Required, but never shown





















































                                          Required, but never shown














                                          Required, but never shown












                                          Required, but never shown







                                          Required, but never shown

































                                          Required, but never shown














                                          Required, but never shown












                                          Required, but never shown







                                          Required, but never shown







                                          Popular posts from this blog

                                          How to reconfigure Docker Trusted Registry 2.x.x to use CEPH FS mount instead of NFS and other traditional...

                                          is 'sed' thread safe

                                          How to make a Squid Proxy server?