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:
git clone
followed by removing the .git
repository directory.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.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 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.
git archive --format zip --output "output.zip" master -0
will give you an uncompressed archive (-0 is the flag for uncompressed). git-scm.com/docs/git-archive. - anyone export
a 250 kB subdirectory directly from remote repository (which could otherwise be 200 MB in size, excluding revisions) - and I will only hit the network for 250 kB (or so) download transfer. With git
, archive
has to be enabled on server (so I can't try it) - clone --depth 1
from server may still retrieve a repo of say 25 MB, where the .git
subfolder alone takes 15MB. Therefore, I'd still say answer is "no". - anyone git archive -o latest.zip HEAD
- anyone Probably the simplest way to achieve this is with git archive
. If you really need just the expanded tree you can do something like this.
git archive master | tar -x -C /somewhere/else
Most of the time that I need to 'export' something from git, I want a compressed archive in any case so I do something like this.
git archive master | bzip2 >source-tree.tar.bz2
ZIP archive:
git archive --format zip --output /full/path/to/zipfile.zip master
git help archive
for more details, it's quite flexible.
Be aware that even though the archive will not contain the .git directory, it will, however, contain other hidden git-specific files like .gitignore, .gitattributes, etc. If you don't want them in the archive, make sure you use the export-ignore attribute in a .gitattributes file and commit this before doing your archive. Read more...
Note: If you are interested in exporting the index, the command is
git checkout-index -a -f --prefix=/destination/path/
(See Greg's answer for more details)
Here's a real-world example using libchrony on Linux:
mkdir $HOME/dev
cd $HOME/dev
pushd /tmp
git clone https://gitlab.com/chrony/libchrony.git
cd libchrony
BRANCH=$(git rev-parse --abbrev-ref HEAD)
git archive -o ../libchrony.zip --prefix="libchrony/" $BRANCH
popd
unzip /tmp/libchrony.zip
Those commands produce a zip file and extract it into $HOME/dev/libchrony
. We can peek into the archive using:
$ unzip -v /tmp/libchrony
Archive: /tmp/libchrony.zip
e0a3807f770b56f6b0e9833254baa7c4fc13564b
Length Method Size Cmpr Date Time CRC-32 Name
-------- ------ ------- ---- ---------- ----- -------- ----
0 Stored 0 0% 2023-07-20 09:37 00000000 libchrony/
49 Defl:N 47 4% 2023-07-20 09:37 37c3f2e2 libchrony/.gitignore
26530 Defl:N 9350 65% 2023-07-20 09:37 5622583e libchrony/COPYING
961 Defl:N 467 51% 2023-07-20 09:37 da9221e3 libchrony/Makefile
475 Defl:N 304 36% 2023-07-20 09:37 cae27f70 libchrony/README.adoc
3313 Defl:N 1119 66% 2023-07-20 09:37 37eb110f libchrony/chrony.h
7673 Defl:N 2261 71% 2023-07-20 09:37 5d455a52 libchrony/client.c
6190 Defl:N 2093 66% 2023-07-20 09:37 7ea9d81b libchrony/example-reports.c
16348 Defl:N 3855 76% 2023-07-20 09:37 e82f5fe3 libchrony/message.c
2946 Defl:N 1099 63% 2023-07-20 09:37 945ee82b libchrony/message.h
-------- ------- --- -------
64485 20595 68% 10 files
Answered 2023-09-20 20:28:25
git archive --format zip --output /full/path master
- anyone git archive --format zip --output /path/to/file.zip --prefix=newdir/ master
the output will be called 'file.zip' but when you unpack it, the top level directory will be 'newdir'. (If you omit the --prefix attribute, the top level dir would be 'file'.) - anyone git archive -o latest.zip HEAD
It create a Zip archive that contains the contents of the latest commit on the current branch. Note that the output format is inferred by the extension of the output file. - anyone I found out what option 2 means. From a repository, you can do:
git checkout-index -a -f --prefix=/destination/path/
The slash at the end of the path is important, otherwise it will result in the files being in /destination with a prefix of 'path'.
Since in a normal situation the index contains the contents of the repository, there is nothing special to do to "read the desired tree into the index". It's already there.
The -a
flag is required to check out all files in the index (I'm not sure what it means to omit this flag in this situation, since it doesn't do what I want). The -f
flag forces overwriting any existing files in the output, which this command doesn't normally do.
This appears to be the sort of "git export" I was looking for.
Answered 2023-09-20 20:28:25
git add
command changes content in the index, so whatever git status
shows as "to be committed" is the differences between HEAD and the contents of the index. - anyone ~
(not '~'
!) will be created in your working dir. There is nothing special about git checkout-index
in this regard: The same is true of mkdir '~/dest'
(don't do that!). Yet another good reason to avoid file names that need quoting (e.g. that have a space in them) :-) - anyone git archive
also works with remote repository.
git archive --format=tar \
--remote=ssh://remote_server/remote_repository master | tar -xf -
To export particular path inside the repo add as many paths as you wish as last argument to git, e.g.:
git archive --format=tar \
--remote=ssh://remote_server/remote_repository master path1/ path2/ | tar -xv
Answered 2023-09-20 20:28:25
git archive --format=tar --prefix=PROJECT_NAME/ --remote=USER@SERVER:PROJECT_NAME.git master | tar -xf -
(ensures your archive is in a folder) - anyone git archive --format=zip --output foo.zip --remote=https://github.com/xxx.git master
And got fatal: Operation not supported by protocol. Unexpected end of command stream. - anyone curl -L https://api.github.com/repos/VENDOR/PROJECT/tarball | tar xzf -
per docs - anyone Just use svn export
.
As far as I know Github does not allow archive --remote
. Although GitHub is svn compatible and they do have all git repos svn
accessible so you could just use svn export
like you normally would with a few adjustments to your GitHub url.
For example to export an entire repository, notice how trunk
in the URL replaces master
(or whatever the project's HEAD branch is set to):
svn export https://github.com/username/repo-name/trunk/
And you can export a single file or even a certain path or folder:
svn export https://github.com/username/repo-name/trunk/src/lib/folder
The HEAD
branch or master branch will be available using trunk
:
svn ls https://github.com/jquery/jquery/trunk
The non-HEAD
branches will be accessible under /branches/
:
svn ls https://github.com/jquery/jquery/branches/2.1-stable
All tags under /tags/
in the same fashion:
svn ls https://github.com/jquery/jquery/tags/2.1.3
Answered 2023-09-20 20:28:25
git archive
works fine with GitHub, as long as you use the git protocol, Just replace https://
with git://
in the URL. I don't know why GitHub doesn't advertise this hidden feature. - anyone fatal: The remote end hung up unexpectedly
. Tried on two different servers with jQuery github repo. - anyone git config url.<base>.insteadOf
to cache the remote repository. I was therefore using a file://
URL in reality. I doubt that git archive
could ever work with git://
URLs since it needs to be able to run git-upload-archive
at the remote end. It should be possible using the ssh
protocol, except that github doesn't allow it (Invalid command: 'git-upload-archive'
). - anyone From the Git Manual:
Using git-checkout-index to "export an entire tree"
The prefix ability basically makes it trivial to use git-checkout-index as an "export as tree" function. Just read the desired tree into the index, and do:
$ git checkout-index --prefix=git-export-dir/ -a
Answered 2023-09-20 20:28:25
git read-tree bar:foo
And then git checkout-index --prefix=export_dir/ -a
after that maybe you should do git update-index master
- anyone I've written a simple wrapper around git-checkout-index
that you can use like this:
git export ~/the/destination/dir
If the destination directory already exists, you'll need to add -f
or --force
.
Installation is simple; just drop the script somewhere in your PATH
, and make sure it's executable.
Answered 2023-09-20 20:28:25
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.
Answered 2023-09-20 20:28:25
The equivalent of
svn export . otherpath
inside an existing repo is
git archive branchname | (cd otherpath; tar x)
The equivalent of
svn export url otherpath
is
git archive --remote=url branchname | (cd otherpath; tar x)
Answered 2023-09-20 20:28:25
git archive --format=tar --prefix=junk/ HEAD | (tar -t -v --full-time -f -)
... However, archiving with timestamps is not exactly trivial, so I posted an example below. - anyone git archive branchname | tar xC otherpath
- anyone C
option to tar is GNU Tar only. - anyone If you're not excluding files with .gitattributes
export-ignore
then try git checkout
mkdir /path/to/checkout/
git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout -f -q
-f
When checking out paths from the index, do not fail upon unmerged entries; instead, unmerged entries are ignored.
and
-q
Avoid verbose
Additionally you can get any Branch or Tag or from a specific Commit Revision like in SVN just adding the SHA1 (SHA1 in Git is the equivalent to the Revision Number in SVN)
mkdir /path/to/checkout/
git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout 2ef2e1f2de5f3d4f5e87df7d8 -f -q -- ./
The /path/to/checkout/
must be empty, Git will not delete any file, but will overwrite files with the same name without any warning
UPDATE:
To avoid the beheaded problem or to leave intact the working repository when using checkout for export with tags, branches or SHA1, you need to add -- ./
at the end
The double dash --
tells git that everything after the dashes are paths or files, and also in this case tells git checkout
to not change the HEAD
Examples:
This command will get just the libs directory and also the readme.txt
file from that exactly commit
git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout fef2e1f2de5f3d4f5e87df7d8 -f -q -- ./libs ./docs/readme.txt
This will create(overwrite) my_file_2_behind_HEAD.txt
two commits behind the head HEAD^2
git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout HEAD^2 -f -q -- ./my_file_2_behind_HEAD.txt
To get the export of another branch
git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout myotherbranch -f -q -- ./
Notice that ./
is relative to the root of the repository
Answered 2023-09-20 20:28:25
I use git-submodules extensively. This one works for me:
rsync -a ./FROM/ ./TO --exclude='.*'
Answered 2023-09-20 20:28:25
.htaccess
? - anyone rsync
lists the argument as --cvs-exclude
. Additionally, it still copies over .gitattributes
and .gitignore
- anyone I have hit this page frequently when looking for a way to export a git repository. My answer to this question considers three properties that svn export has by design compared to git, since svn follows a centralized repository approach:
It minimizes the traffic to a remote repository location by not exporting all revisions
It does not include meta information in the export directory
Exporting a certain branch using svn is accomplished by specifying the appropriate path
git clone --depth 1 --branch main git://git.somewhere destination_path
rm -rf destination_path/.git
When building a certain release it is useful to clone a stable branch as for example --branch stable
or --branch release/0.9
.
Answered 2023-09-20 20:28:25
git archive | tar
approach is inapplicable to POSIX-incompatible shell environments (e.g., AppVeyor's CMD- or PowerShell-based CI), which is non-ideal. The git checkout
approach modifies the index of the main working tree, which is awful. The git checkout-index
approach requires the index of the main working tree to be modified beforehand, which is even awful-er. The traditional git clone
approach clones the entirety of the repository's history before deleting that history, which is wasteful. This is the only sane solution left. - anyone file://
protocol (e.g., git clone --depth 1 --branch v3.14.15 file:///home/me/src_repo trg_repo
). Failing to do so will emit "warning: --depth is ignored in local clones; use file:// instead."
and perform a standard rather than shallow clone, defeating the entire purpose of this answer. Salud! - anyone master
--> main
as of today in most repos - anyone This will copy all contents, minus the .dot files. I use this to export git cloned projects into my web app's git repo without the .git stuff.
cp -R ./path-to-git-repo /path/to/destination/
Plain old bash works just great :)
Answered 2023-09-20 20:28:25
.gitignore
, this won't. - anyone As simple as clone then delete the .git folder:
git clone url_of_your_repo path_to_export && rm -rf path_to_export/.git
Answered 2023-09-20 20:28:25
--depth 1
. Third, even if this answer is improved, it adds nothing to the Lars Schillingmann's answer. - anyone 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
Answered 2023-09-20 20:28:25
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
Answered 2023-09-20 20:28:25
I just want to point out that in the case that you are
Then you can just use cp foo [destination]
instead of the mentioned git-archive master foo | -x -C [destination]
.
Answered 2023-09-20 20:28:25
You can archive a remote repo at any commit as zip file.
git archive --format=zip --output=archive.zip --remote=USERNAME@HOSTNAME:PROJECTNAME.git HASHOFGITCOMMIT
Answered 2023-09-20 20:28:25
If you want something that works with submodules this might be worth a go.
Note:
Assumptions:
cd MASTER_DIR && tar -zcvf ../DEST_DIR/export.tar.gz --exclude='.git*' . && cd ../DEST_DIR/ && tar xvfz export.tar.gz && rm export.tar.gz
Answered 2023-09-20 20:28:25
My preference would actually be to have a dist target in your Makefile (or other build system) that exports a distributable archive of your code (.tar.bz2, .zip, .jar, or whatever is appropriate). If you happen to be using GNU autotools or Perl's MakeMaker systems, I think this exists for you automatically. If not, I highly recommend adding it.
ETA (2012-09-06): Wow, harsh downvotes. I still believe it is better to build your distributions with your build tools rather than your source code control tool. I believe in building artifacts with build tools. In my current job, our main product is built with an ant target. We are in the midst of switching source code control systems, and the presence of this ant target means one less hassle in migration.
Answered 2023-09-20 20:28:25
As I understand the question, it it more about downloading just certain state from the server, without history, and without data of other branches, rather than extracting a state from a local repository (as many anwsers here do).
That can be done like this:
git clone -b someBranch --depth 1 --single-branch git://somewhere.com/repo.git \
&& rm -rf repo/.git/
--single-branch
is available since Git 1.7.10 (April 2012).--depth
is (was?) reportedly faulty, but for the case of an export, the mentioned issues should not matter.Answered 2023-09-20 20:28:25
--depth
, which implies --single-branch
unless --no-single-branch
is given, which means this has probably the same effect. Not sure though, some expert may confirm? - anyone Bash-implementation of git-export.
I have segmented the .empty file creation and removal processes on their own function, with the purpose of re-using them in the 'git-archive' implementation (will be posted later on).
I have also added the '.gitattributes' file to the process in order to remove un-wanted files from the target export folder. Included verbosity to the process while making the 'git-export' function more efficient.
EMPTY_FILE=".empty";
function create_empty () {
## Processing path (target-dir):
TRG_PATH="${1}";
## Component(s):
EXCLUDE_DIR=".git";
echo -en "\nAdding '${EMPTY_FILE}' files to empty folder(s): ...";
find ${TRG_PATH} -not -path "*/${EXCLUDE_DIR}/*" -type d -empty -exec touch {}/${EMPTY_FILE} \;
#echo "done.";
## Purging SRC/TRG_DIRs variable(s):
unset TRG_PATH EMPTY_FILE EXCLUDE_DIR;
return 0;
}
declare -a GIT_EXCLUDE;
function load_exclude () {
SRC_PATH="${1}";
ITEMS=0; while read LINE; do
# echo -e "Line [${ITEMS}]: '${LINE%%\ *}'";
GIT_EXCLUDE[((ITEMS++))]=${LINE%%\ *};
done < ${SRC_PATH}/.gitattributes;
GIT_EXCLUDE[${ITEMS}]="${EMPTY_FILE}";
## Purging variable(s):
unset SRC_PATH ITEMS;
return 0;
}
function purge_empty () {
## Processing path (Source/Target-dir):
SRC_PATH="${1}";
TRG_PATH="${2}";
echo -e "\nPurging Git-Specific component(s): ... ";
find ${SRC_PATH} -type f -name ${EMPTY_FILE} -exec /bin/rm '{}' \;
for xRULE in ${GIT_EXCLUDE[@]}; do
echo -en " '${TRG_PATH}/{${xRULE}}' files ... ";
find ${TRG_PATH} -type f -name "${xRULE}" -exec /bin/rm -rf '{}' \;
echo "done.'";
done;
echo -e "done.\n"
## Purging SRC/TRG_PATHs variable(s):
unset SRC_PATH; unset TRG_PATH;
return 0;
}
function git-export () {
TRG_DIR="${1}"; SRC_DIR="${2}";
if [ -z "${SRC_DIR}" ]; then SRC_DIR="${PWD}"; fi
load_exclude "${SRC_DIR}";
## Dynamically added '.empty' files to the Git-Structure:
create_empty "${SRC_DIR}";
GIT_COMMIT="Including '${EMPTY_FILE}' files into Git-Index container."; #echo -e "\n${GIT_COMMIT}";
git add .; git commit --quiet --all --verbose --message "${GIT_COMMIT}";
if [ "${?}" -eq 0 ]; then echo " done."; fi
/bin/rm -rf ${TRG_DIR} && mkdir -p "${TRG_DIR}";
echo -en "\nChecking-Out Index component(s): ... ";
git checkout-index --prefix=${TRG_DIR}/ -q -f -a
## Reset: --mixed = reset HEAD and index:
if [ "${?}" -eq 0 ]; then
echo "done."; echo -en "Resetting HEAD and Index: ... ";
git reset --soft HEAD^;
if [ "${?}" -eq 0 ]; then
echo "done.";
## Purging Git-specific components and '.empty' files from Target-Dir:
purge_empty "${SRC_DIR}" "${TRG_DIR}"
else echo "failed.";
fi
## Archiving exported-content:
echo -en "Archiving Checked-Out component(s): ... ";
if [ -f "${TRG_DIR}.tgz" ]; then /bin/rm ${TRG_DIR}.tgz; fi
cd ${TRG_DIR} && tar -czf ${TRG_DIR}.tgz ./; cd ${SRC_DIR}
echo "done.";
## Listing *.tgz file attributes:
## Warning: Un-TAR this file to a specific directory:
ls -al ${TRG_DIR}.tgz
else echo "failed.";
fi
## Purgin all references to Un-Staged File(s):
git reset HEAD;
## Purging SRC/TRG_DIRs variable(s):
unset SRC_DIR; unset TRG_DIR;
echo "";
return 0;
}
Output:
$ git-export /tmp/rel-1.0.0
Adding '.empty' files to empty folder(s): ... done.
Checking-Out Index component(s): ... done.
Resetting HEAD and Index: ... done.
Purging Git-Specific component(s): ...
'/tmp/rel-1.0.0/{.buildpath}' files ... done.'
'/tmp/rel-1.0.0/{.project}' files ... done.'
'/tmp/rel-1.0.0/{.gitignore}' files ... done.'
'/tmp/rel-1.0.0/{.git}' files ... done.'
'/tmp/rel-1.0.0/{.gitattributes}' files ... done.'
'/tmp/rel-1.0.0/{*.mno}' files ... done.'
'/tmp/rel-1.0.0/{*~}' files ... done.'
'/tmp/rel-1.0.0/{.*~}' files ... done.'
'/tmp/rel-1.0.0/{*.swp}' files ... done.'
'/tmp/rel-1.0.0/{*.swo}' files ... done.'
'/tmp/rel-1.0.0/{.DS_Store}' files ... done.'
'/tmp/rel-1.0.0/{.settings}' files ... done.'
'/tmp/rel-1.0.0/{.empty}' files ... done.'
done.
Archiving Checked-Out component(s): ... done.
-rw-r--r-- 1 admin wheel 25445901 3 Nov 12:57 /tmp/rel-1.0.0.tgz
I have now incorporated the 'git archive' functionality into a single process that makes use of 'create_empty' function and other features.
function git-archive () {
PREFIX="${1}"; ## sudo mkdir -p ${PREFIX}
REPO_PATH="`echo "${2}"|awk -F: '{print $1}'`";
RELEASE="`echo "${2}"|awk -F: '{print $2}'`";
USER_PATH="${PWD}";
echo "$PREFIX $REPO_PATH $RELEASE $USER_PATH";
## Dynamically added '.empty' files to the Git-Structure:
cd "${REPO_PATH}"; populate_empty .; echo -en "\n";
# git archive --prefix=git-1.4.0/ -o git-1.4.0.tar.gz v1.4.0
# e.g.: git-archive /var/www/htdocs /repos/domain.name/website:rel-1.0.0 --explode
OUTPUT_FILE="${USER_PATH}/${RELEASE}.tar.gz";
git archive --verbose --prefix=${PREFIX}/ -o ${OUTPUT_FILE} ${RELEASE}
cd "${USER_PATH}";
if [[ "${3}" =~ [--explode] ]]; then
if [ -d "./${RELEASE}" ]; then /bin/rm -rf "./${RELEASE}"; fi
mkdir -p ./${RELEASE}; tar -xzf "${OUTPUT_FILE}" -C ./${RELEASE}
fi
## Purging SRC/TRG_DIRs variable(s):
unset PREFIX REPO_PATH RELEASE USER_PATH OUTPUT_FILE;
return 0;
}
Answered 2023-09-20 20:28:25
a git export to a zip archive while adding a prefix (e.g. directory name):
git archive master --prefix=directoryWithinZip/ --format=zip -o out.zip
Answered 2023-09-20 20:28:25
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
-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
Answered 2023-09-20 20:28:25
By far the easiest way i've seen to do it (and works on windows as well) is git bundle
:
git bundle create /some/bundle/path.bundle --all
See this answer for more details: How can I copy my git repository from my windows machine to a linux machine via usb drive?
Answered 2023-09-20 20:28:25
git bundle
includes the .git
folder, which is what the OP does not want; git archive
seems the more appropriate way - anyone --all
switch? - anyone I needed this for a deploy script and I couldn't use any of the above mentioned approaches. Instead I figured out a different solution:
#!/bin/sh
[ $# -eq 2 ] || echo "USAGE $0 REPOSITORY DESTINATION" && exit 1
REPOSITORY=$1
DESTINATION=$2
TMPNAME="/tmp/$(basename $REPOSITORY).$$"
git clone $REPOSITORY $TMPNAME
rm -rf $TMPNAME/.git
mkdir -p $DESTINATION
cp -r $TMPNAME/* $DESTINATION
rm -rf $TMPNAME
Answered 2023-09-20 20:28:25
mkdir -p "$2" && git --git-dir="$1" archive HEAD | tar -x -C "$2"
but somewhat longer winded. - anyone Doing it the easy way, this is a function for .bash_profile, it directly unzips the archive on current location, configure first your usual [url:path]. NOTE: With this function you avoid the clone operation, it gets directly from the remote repo.
gitss() {
URL=[url:path]
TMPFILE="`/bin/tempfile`"
if [ "$1" = "" ]; then
echo -e "Use: gitss repo [tree/commit]\n"
return
fi
if [ "$2" = "" ]; then
TREEISH="HEAD"
else
TREEISH="$2"
fi
echo "Getting $1/$TREEISH..."
git archive --format=zip --remote=$URL/$1 $TREEISH > $TMPFILE && unzip $TMPFILE && echo -e "\nDone\n"
rm $TMPFILE
}
Alias for .gitconfig, same configuration required (TAKE CARE executing the command inside .git projects, it ALWAYS jumps to the base dir previously as said here, until this is fixed I personally prefer the function
ss = !env GIT_TMPFILE="`/bin/tempfile`" sh -c 'git archive --format=zip --remote=[url:path]/$1 $2 \ > $GIT_TMPFILE && unzip $GIT_TMPFILE && rm $GIT_TMPFILE' -
Answered 2023-09-20 20:28:25
I have another solution that works fine if you have a local copy of the repository on the machine where you would like to create the export. In this case move to this repository directory, and enter this command:
GIT_WORK_TREE=outputdirectory git checkout -f
This is particularly useful if you manage a website with a git repository and would like to checkout a clean version in /var/www/
. In this case, add thiscommand in a .git/hooks/post-receive
script (hooks/post-receive
on a bare repository, which is more suitable in this situation)
Answered 2023-09-20 20:28:25
I think @Aredridel's post was closest, but there's a bit more to that - so I will add this here; the thing is, in svn
, if you're in a subfolder of a repo, and you do:
/media/disk/repo_svn/subdir$ svn export . /media/disk2/repo_svn_B/subdir
then svn
will export all files that are under revision control (they could have also freshly Added; or Modified status) - and if you have other "junk" in that directory (and I'm not counting .svn
subfolders here, but visible stuff like .o
files), it will not be exported; only those files registered by the SVN repo will be exported. For me, one nice thing is that this export also includes files with local changes that have not been committed yet; and another nice thing is that the timestamps of the exported files are the same as the original ones. Or, as svn help export
puts it:
- Exports a clean directory tree from the working copy specified by PATH1, at revision REV if it is given, otherwise at WORKING, into PATH2. ... If REV is not specified, all local changes will be preserved. Files not under version control will not be copied.
To realize that git
will not preserve the timestamps, compare the output of these commands (in a subfolder of a git
repo of your choice):
/media/disk/git_svn/subdir$ ls -la .
... and:
/media/disk/git_svn/subdir$ git archive --format=tar --prefix=junk/ HEAD | (tar -t -v --full-time -f -)
... and I, in any case, notice that git archive
causes all the timestamps of the archived file to be the same! git help archive
says:
git archive behaves differently when given a tree ID versus when given a commit ID or tag ID. In the first case the current time is used as the modification time of each file in the archive. In the latter case the commit time as recorded in the referenced commit object is used instead.
... but apparently both cases set the "modification time of each file"; thereby not preserving the actual timestamps of those files!
So, in order to also preserve the timestamps, here is a bash
script, which is actually a "one-liner", albeit somewhat complicated - so below it is posted in multiple lines:
/media/disk/git_svn/subdir$ git archive --format=tar master | (tar tf -) | (\
DEST="/media/diskC/tmp/subdirB"; \
CWD="$PWD"; \
while read line; do \
DN=$(dirname "$line"); BN=$(basename "$line"); \
SRD="$CWD"; TGD="$DEST"; \
if [ "$DN" != "." ]; then \
SRD="$SRD/$DN" ; TGD="$TGD/$DN" ; \
if [ ! -d "$TGD" ] ; then \
CMD="mkdir \"$TGD\"; touch -r \"$SRD\" \"$TGD\""; \
echo "$CMD"; \
eval "$CMD"; \
fi; \
fi; \
CMD="cp -a \"$SRD/$BN\" \"$TGD/\""; \
echo "$CMD"; \
eval "$CMD"; \
done \
)
Note that it is assumed that you're exporting the contents in "current" directory (above, /media/disk/git_svn/subdir
) - and the destination you're exporting into is somewhat inconveniently placed, but it is in DEST
environment variable. Note that with this script; you must create the DEST
directory manually yourself, before running the above script.
After the script is ran, you should be able to compare:
ls -la /media/disk/git_svn/subdir
ls -la /media/diskC/tmp/subdirB # DEST
... and hopefully see the same timestamps (for those files that were under version control).
Hope this helps someone,
Cheers!
Answered 2023-09-20 20:28:25
If you need submodules as well, this should do the trick: https://github.com/meitar/git-archive-all.sh/wiki
Answered 2023-09-20 20:28:25
i have the following utility function in my .bashrc file: it creates an archive of the current branch in a git repository.
function garchive()
{
if [[ "x$1" == "x-h" || "x$1" == "x" ]]; then
cat <<EOF
Usage: garchive <archive-name>
create zip archive of the current branch into <archive-name>
EOF
else
local oname=$1
set -x
local bname=$(git branch | grep -F "*" | sed -e 's#^*##')
git archive --format zip --output ${oname} ${bname}
set +x
fi
}
Answered 2023-09-20 20:28:25