23

Is it possible to “checkout” to a location outside of the repository? What I mean is a clone of a branch without the “.git” directory.

For example: Use git to manage a website. You edit some files, commit and copy the files to a web server via WebDAV. The WebDAV-path would be the location outside the repository, which shouldn't contain the “.git”.

This may not be the problem for which git was build, but is this possible?

slhck
  • 223,558
  • 70
  • 607
  • 592
user240826
  • 331
  • 1
  • 2
  • 3
  • You can also use `git show` to check out files to any path you want, as this answer shows here: https://stackoverflow.com/questions/888414/git-checkout-older-revision-of-a-file-under-a-new-name/888623#888623. – Gabriel Staples Feb 12 '21 at 06:50

3 Answers3

21

Yes, this is certainly possible.

Lets say I have a bare repository named /srv/production.git on the destination system/server.

On the destination system I can use the command cd /srv/production.git; GIT_WORK_TREE=/srv/production-www/ git checkout -f

If I am in a non-bare repository the command is slightly different. Lets say I have a non-bare respository at /srv/testing. To checkout that I would use cd /srv/testing/.git; GIT_WORK_TREE=/srv/production-www/ git checkout -f

In fact on my system I even automate this in a post-commit hook in my production.git repository. So when you push to production.git the latest version is automatically check out to the web root.

#!/bin/sh
#
# An example hook script that is called after a successful
# commit is made.
#
# To enable this hook, rename this file to "post-commit".

GIT_WORK_TREE=/srv/production-www/ git checkout -f
# ... misc other commands to verify permissions are set correctly.

If your only access to the remote system is webdav, it certainly should be possible to write a post-commit hook that will checkout to the webdav host, either directly or to a temporary location, which you can then script an upload.

Tobias Kienzler
  • 4,421
  • 7
  • 44
  • 76
Zoredache
  • 19,828
  • 8
  • 50
  • 72
7

If you just want the files, you can use git archive. Usually it writes to an archive like tarballs or ZIP, but you can pipe it as well:

git archive master | tar -x -C /some/path

Here, master obviously is the branch you want to archive, and /some/path will contain just the files – no .git or .gitignore.


Or you can use git checkout-index which more closely resembles a "checkout" of files:

git checkout-index -f -a --prefix=/some/path/

Here, the -a option tells git to check out all files. The prefix will be prepended to the output. Somebody also wrote a wrapper around this to give a git export.

slhck
  • 223,558
  • 70
  • 607
  • 592
  • 2
    I think you are making this more difficult than it needs to be. Just run `GIT_WORK_TREE=/destinationpath git checkout -f` while your current directory is at the top of a bare repository, or the .git subdirectory. You will get a checkout to /destinationpath – Zoredache Jul 25 '13 at 22:59
  • Ok, I must have somehow missed that option, +1 to you. – slhck Jul 26 '13 at 06:53
  • 1
    I find this option way more intuitive, to be honest. And less error prone. – Minix Jul 11 '18 at 13:37
3

Since Git 1.8.5, you can use -C <path> option, to run as if git was started in <path>, instead of the current working directory.

On older Git versions, use --work-tree option. For example::

repo_url=https://github.com/owner/project.git
repo_dir=$(basename $repo_url .git)
git clone $repo_url
git --work-tree=$repo_dir checkout $branch
Noam Manos
  • 1,804
  • 1
  • 20
  • 20