Do a “git export” (like “svn export”)?

2018-12-31 02:58发布

I've been wondering whether there is a good "git export" solution that creates a copy of a tree without the .git repository directory. There are at least three methods I know of:

  1. git clone followed by removing the .git repository directory.
  2. git checkout-index alludes to this functionality but starts with "Just read the desired tree into the index..." which I'm not entirely sure how to do.
  3. git-export is a third party script that essentially does a git clone into a temporary location followed by rsync --exclude='.git' into the final destination.

None of these solutions really strike me as being satisfactory. The closest one to svn export might be option 1, because both those require the target directory to be empty first. But option 2 seems even better, assuming I can figure out what it means to read a tree into the index.

30条回答
高级女魔头
2楼-- · 2018-12-31 03:25

The option 1 sounds not too efficient. What if there is no space in the client to do a clone and then remove the .git folder?

Today I found myself trying to do this, where the client is a Raspberry Pi with almost no space left. Furthermore, I also want to exclude some heavy folder from the repository.

Option 2 and others answers here do not help in this scenario. Neither git archive (because require to commit a .gitattributes file, and I don't want to save this exclusion in the repository).

Here I share my solution, similar to option 3, but without the need of git clone:

tmp=`mktemp`
git ls-tree --name-only -r HEAD > $tmp
rsync -avz --files-from=$tmp --exclude='fonts/*' . raspberry:

Changing the rsync line for an equivalent line for compress will also work as a git archive but with a sort of exclusion option (as is asked here).

查看更多
有味是清欢
3楼-- · 2018-12-31 03:28

Yes, this is a clean and neat command to archive your code without any git inclusion in the archive and is good to pass around without worrying about any git commit history.

git archive --format zip --output /full/path/to/zipfile.zip master 
查看更多
泛滥B
4楼-- · 2018-12-31 03:28

This will copy the files in a range of commits (C to G) to a tar file. Note: this will only get the files commited. Not the entire repository. Slightly modified from Here

Example Commit History

A --> B --> C --> D --> E --> F --> G --> H --> I

git diff-tree -r --no-commit-id --name-only --diff-filter=ACMRT C~..G | xargs tar -rf myTarFile.tar

git-diff-tree Manual Page

-r --> recurse into sub-trees

--no-commit-id --> git diff-tree outputs a line with the commit ID when applicable. This flag suppressed the commit ID output.

--name-only --> Show only names of changed files.

--diff-filter=ACMRT --> Select only these files. See here for full list of files

C..G --> Files in this range of commits

C~ --> Include files from Commit C. Not just files since Commit C.

| xargs tar -rf myTarFile --> outputs to tar

查看更多
骚的不知所云
5楼-- · 2018-12-31 03:29

It appears that this is less of an issue with Git than SVN. Git only puts a .git folder in the repository root, whereas SVN puts a .svn folder in every subdirectory. So "svn export" avoids recursive command-line magic, whereas with Git recursion is not necessary.

查看更多
萌妹纸的霸气范
6楼-- · 2018-12-31 03:29

For GitHub users, the git archive --remote method won't work directly, as the export URL is ephemeral. You must ask GitHub for the URL, then download that URL. curl makes that easy:

curl -L https://api.github.com/repos/VENDOR/PROJECT/tarball | tar xzf -

This will give you the exported code in a local directory. Example:

$ curl -L https://api.github.com/repos/jpic/bashworks/tarball | tar xzf -
$ ls jpic-bashworks-34f4441/
break  conf  docs  hack  LICENSE  mlog  module  mpd  mtests  os  README.rst  remote  todo  vcs  vps  wepcrack

Edit
If you want the code put into a specific, existing directory (rather than the random one from github):

curl -L https://api.github.com/repos/VENDOR/PROJECT/tarball | \
tar xzC /path/you/want --strip 1
查看更多
裙下三千臣
7楼-- · 2018-12-31 03:31

I use git-submodules extensively. This one works for me:

rsync -a ./FROM/ ./TO --exclude='.*'
查看更多
登录 后发表回答