git checkout branch from outside

20,160

Solution 1

You can use --git-dir to specify the .git directory to use as the repository, and --work-tree to specify the working tree to to the checkout in. See the git man page for details.

git --git-dir=file-system-folder/.git --work-tree=file-system-folder checkout existing-branch

Solution 2

Since Git version 1.8.5, you can also use -C <path> option. Be sure to use it before any other command:

git -C ~/my-git-repo checkout master

Note that it doesn't have to be specifically the .git folder. Here is the man documenation:

-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>.

       This option affects options that expect path name like --git-dir
       and --work-tree in that their interpretations of the path names
       would be made relative to the working directory caused by the -C option.
       For example the following invocations are equivalent:

           git --git-dir=a.git --work-tree=b -C c status
           git --git-dir=c/a.git --work-tree=c/b status

Solution 3

git clone ./foo ./foo-copy
git --git-dir=./foo-copy/.git --work-tree=./foo-copy checkout branch

Solution 4

You're quite welcome to use --git-dir and --work-tree to avoid cd'ing, but honestly, it's easier just to cd. To avoid having to cd back, you can do it in a subshell:

git clone foo foo-copy
(cd foo-copy && git checkout branch)

Of course, in this specific case, you don't actually need two commands:

git clone -b <branch-to-checkout> foo foo-copy 

Solution 5

git 2.5 added the ability to have multiple working trees using git worktree. So this case, you'd use something like

git worktree add -b new-branch-name ../dir-name existing-branch

you can then change to dir-name and make your commits as usual. The commits will end up in your original repository (where you used worktree add).

When you're done and everything you want is committed, you can delete the dir-name folder and run git worktree prune to clean up the orphaned worktree in your repo.

Share:
20,160
eistrati
Author by

eistrati

Proud Father. Lucky Husband. Co-Founder @AdTechMediaPro. AWS Tech Partner @MitocGroup. Former @AWScloud and @HearstCorp.

Updated on September 05, 2020

Comments

  • eistrati
    eistrati over 3 years

    Problem: I need somehow to checkout an existing branch of a project that is already cloned locally on my file system without being in that particular folder of this project.

    Solution: I'm trying to do the following:

    1. git clone 'github-project-url' 'file-system-folder'
    2. git checkout 'existing-branch' 'file-system-folder'

    I do realize that second step is not quite right, but I also am trying to avoid to cd 'file-system-folder'.

  • Brian Campbell
    Brian Campbell almost 13 years
    This won't work. --git-dir needs the actual .git directory; and this will do the checkout in the current working directory, not in the repository. You need to pass both --git-dir and --work-tree.
  • Victor Zamanian
    Victor Zamanian almost 13 years
    Also it seems to me during testing that you must pass those flags to git itself, and not the checkout subcommand.
  • eistrati
    eistrati almost 13 years
    Well, when you create a command line script, it's not easier ;) Anyway thank you for your feedback!
  • Robin Green
    Robin Green almost 13 years
    Um, eistrati, anything you can type at the shell prompt, you can put in a script! What's the problem?
  • eistrati
    eistrati almost 13 years
    No problem, just why would I do 3 operations (cd folder && git checkout && cd back) when I can do only one (git checkout with specified options)?
  • Cascabel
    Cascabel almost 13 years
    @eistrati: It's definitely easier. What matters isn't the number of commands but how much typing it takes, and you have to type the directory twice to do it with just the git command. And even if you only had to type it once, it'd still be essentially the same length: cd foo && git checkout vs git --dir=foo checkout. It also only takes two commands; you don't have to cd back if you ran it in a subtree.
  • Cascabel
    Cascabel almost 13 years
    Also, I don't know if you missed this, but I told you how to do all of what you want in a single command, not just the checkout.
  • eistrati
    eistrati almost 13 years
    No, I didn't miss it, thank you! Bottom line, I find one command easier and more straight forward than three. As I said, I'm writing a script that does tons of other things besides this one, so less things to handle is better. Enough said...
  • Cascabel
    Cascabel almost 13 years
    @eistrati: You're of course free to write your scripts however you want, but more commands of shorter total length is not really more to handle, and if others are working on your scripts, you might find that they too disagree with you. (cd <dir> && ...) is a very, very common and well-understood idiom.
  • Cascabel
    Cascabel almost 13 years
    +1: Certainly the best in terms of the OP's preferences, though if you happen to be looking for the shortest way to do it instead of the fewest commands, cd in a subshell is really quite nice.
  • Mark Longair
    Mark Longair almost 13 years
    In addition, the semantics of --git-dir and --work-tree are really non-obvious. If you want to use them and avoid unpleasant surprises, always set both of them, and only use absolute paths. @Jefromi's advice (to avoid those issues completely) is very sound in my experience.
  • Keith
    Keith over 6 years
    Did you actually do this? I don't see your code example working on my pc, nor does it look like the example you showed (which has --git-dir and --work-tree.
  • General Redneck
    General Redneck over 6 years
    Yep I've used like so with tons of different got commands. git clone $ACQUIA_REPO ~/acquia; git -C ~/acquia checkout -b $CIRCLE_BRANCH; git -C ~/acquia log; git -C ~/acquia add .; git -C ~/acquia commit -am "$( cat
  • General Redneck
    General Redneck over 6 years
    The man page has git-dir and work-tree. To simply perform a git command on a git repo with a .git folder -C is all you need.
  • dtudury
    dtudury over 5 years
    sorry... down-voted this a month ago but after rereading the comments today I think this is the right answer (SO won't let me change my downvote to an upvote)
  • solr
    solr almost 5 years
    Wasn't aware of this, should be the official answer -- thanks, General