Git Clone: Just the files, please?

后端 未结 8 653
北海茫月
北海茫月 2021-01-30 00:25

I want to clone a GIT repo and NOT end up with a .git directory. In other words I just want the files. Is there a way to do this?

git clone --no-chec

相关标签:
8条回答
  • 2021-01-30 00:53

    The git command that would be the closest from what you are looking for would by git archive.
    See backing up project which uses git: it will include in an archive all files (including submodules if you are using the git-archive-all script)

    You can then use that archive anywhere, giving you back only files, no .git directory.

    git archive --remote=<repository URL> | tar -t
    

    If you need folders and files just from the first level:

    git archive --remote=<repository URL> | tar -t --exclude="*/*"
    

    To list only first-level folders of a remote repo:

    git archive --remote=<repository URL> | tar -t --exclude="*/*" | grep "/"
    

    Note: that does not work for GitHub (not supported)

    So you would need to clone (shallow to quicken the clone step), and then archive locally:

    git clone --depth=1 git@github.com:xxx/yyy.git
    cd yyy
    git archive --format=tar aTag -o aTag.tar
    

    Another option would be to do a shallow clone (as mentioned below), but locating the .git folder elsewhere.

    git --git-dir=/path/to/another/folder.git clone --depth=1 /url/to/repo
    

    The repo folder would include only the file, without .git.

    Note: git --git-dir is an option of the command git, not git clone.


    Update with Git 2.14.X/2.15 (Q4 2017): it will make sure to avoid adding empty folders.

    "git archive", especially when used with pathspec, stored an empty directory in its output, even though Git itself never does so.
    This has been fixed.

    See commit 4318094 (12 Sep 2017) by René Scharfe (``).
    Suggested-by: Jeff King (peff).
    (Merged by Junio C Hamano -- gitster -- in commit 62b1cb7, 25 Sep 2017)

    archive: don't add empty directories to archives

    While git doesn't track empty directories, git archive can be tricked into putting some into archives.
    While that is supported by the object database, it can't be represented in the index and thus it's unlikely to occur in the wild.

    As empty directories are not supported by git, they should also not be written into archives.
    If an empty directory is really needed then it can be tracked and archived by placing an empty .gitignore file in it.

    0 讨论(0)
  • 2021-01-30 00:57

    It sounds like you just want a copy of the source code. If so why not just copy the directory and exclude the .git directory from the copy?

    0 讨论(0)
  • 2021-01-30 00:59

    you can create a shallow clone to only get the last few revisions:

     git clone --depth 1 git://url
    

    then either simply delete the .git directory or use git archive to export your tree.

    0 讨论(0)
  • 2021-01-30 01:04

    No need to use git at all, just append "/zipball/master/" to URL (source).

    Downloading

    This solution is the closest to "Download ZIP" button on github page. One advantage is lack of .git directory. The other one - it downloads single ZIP file instead of each file one by one, and this can make huge difference. It can be done from command line by wget: wget -O "$(basename $REPO_URL)".zip "$REPO_URL"/zipball/master/. The only problem is, that some repositories might not have master branch at all. If this is the case, "master" in URL should be replaced by appropriate branch.

    Unzipping

    Once the ZIP is there, the final unzipped directory name may still be pretty weird and unexpected. To fix this, name can be extracted by this script, and mv-ed to basename of the URL. Final script.sh could look something like (evals for dealing with spaces):

    #Script for downloading from github. If no BRANCH_NAME is given, default is "master".
    #usage: script.sh URL [BRANCH_NAME]
    __repo_name__='basename "$1"'
    __repo_name__="$(eval $__repo_name__)"
    __branch__="${2:-master}"
    #downloading
    if [ ! -e ./"$__repo_name__"".zip" ] ; then
    wget -O "$__repo_name__"".zip" "$1""/zipball/$__branch__/"
    fi
    #unpacking and renaming
    if [ ! -e ./"$__repo_name__" ] ; then
    unzip "$__repo_name__"".zip" && 
    __dir_name__="$(unzip -qql $__repo_name__.zip | sed -r '1 {s/([ ]+[^ ]+){3}\s+//;q}')" &&
    rm "$__repo_name__"".zip" &&
    mv "$__dir_name__" "$__repo_name__"
    fi
    

    Maintaining

    This approach shoud do the work for "just the files", and it is great for quick single-use access to small repositories.

    However. If the source is rather big, and the only possibility to update is to download and rebuild all, then (to the best of my knowledge) there is no possibility to update .git-less directory, so the full repo has to be downloaded again. Then the best solution is - as VonC has already explained - to stick with shallow copy git clone --depth 1 $REPO_URL. But what next? To "check for updates" see link, and to update see great wiki-like answer.

    0 讨论(0)
  • 2021-01-30 01:08

    git checkout -f

    There's another way to do this by splitting the repo from the working tree.

    This method is useful if you need to update these git-less git files on a regular basis. For instance, I use it when I need to check out source files and build an artifact, then copy the artifact into a different repo just for deployment to a server, and I also use it when pushing source code to a server when I want the source code to checkout and build into the www directory.

    We'll make two folders, one for the git one for the working files:

    mkdir workingfiles
    mkdir barerepo.git
    

    initialize a bare git repo:

    cd barerepo.git
    git --bare init 
    

    Then create a post-receive hook:

    touch hooks/post-receive
    chmod ug+x hooks/post-receive
    

    Edit post-receive in your favorite editor:

    GIT_WORK_TREE=/path/to/workingfiles git checkout -f
    # optional stuff:
    cd down/to/some/directory
    [do some stuff]
    

    Add this as a remote:

    git remote add myserver ssh://user@host:/path/to/barerepo.git
    

    Now every time you push to this bare repo it will checkout the working tree to /workingfiles/. But /workingfiles/ itself is not under version control; running git status in /workingfiles/ will give the error fatal: Not a git repository (or any parent up to mount point /data). It's just plain files.

    Unlike other solutions rm -r .git command is not needed, so if /workingfiles/ is some other git repo you don't have to worry about the command used removing the other repo's git files.

    0 讨论(0)
  • 2021-01-30 01:10
    git archive --format=tar --remote=<repository URL> HEAD | tar xf -
    

    taken from here

    0 讨论(0)
提交回复
热议问题