Git has the very handy archive
command which allows me to make a copy of a particular commit in a .zip archive like so:
git archi开发者_如何转开发ve -o ../latest.zip some-commit
This will contain the entire working tree for that commit. Usually I just need the changed files since a previous release. Currently I use this to get those files into a zip:
git diff --name-only previous-commit latest-commit | zip ../changes.zip -@
This will however zip files from my working copy, which may have uncommitted changes. Is there some way to get only the changed files as they were committed directly into a zip?
git archive
will accept paths as arguments. All you should need to do is:
git archive -o ../latest.zip some-commit $(git diff --name-only earlier-commit some-commit)
or if you have files with spaces (or other special characters) in them, use xargs:
git diff --name-only earlier-commit some-commit | xargs -d'\n' git archive -o ../latest.zip some-commit
If you don't have xargs properly installed, you could cook up an alternative:
#!/bin/bash
IFS=$'\n'
files=($(git diff --name-only earlier-commit some-commit))
git archive -o ../latest.zip some-commit "${files[@]}"
Written as a shell script, but should work as a one-liner too. Alternatively, change earlier-commit
, some-commit
, and ../latest.zip
to $1
$2
and $3
and you've got yourself a reusable script.
If creating a patch is not an option, then how about something like this:
git stash
git checkout latest-commit
git diff --name-only previous-commit | zip ../changes.zip -@
git checkout master
git stash apply
NOTE: The git stash
and git stash apply
are only needed if you have working copy changes that have not been committed.
NOTE 2: git checkout latest-commit
will put you on a detached head. Be sure to git checkout master
when you are done or you could wind up having problems with future commits.
I have comme up with a solution, one line and quite simple:
zip archive.zip $(git diff-tree --no-commit-id --name-only -r latest-commit)
You can as well use any other archiving method like tar with this method.
In order to implement something useful to solve such a question for me, I've implemented a simple bash script. The script takes a revision hash and creates a tar.gz archive with all changed files including directory hierarchy. Anyone could use it or modify, I would be happy if it will help someone.
Just run script in the directory that is root for git repository and pass revision hash to the command line argumens.
Link to the script on hithub
try this, generate a patch_Ymd.zip from last commit:
git diff HEAD@{1} --name-only -z | xargs -0 git archive HEAD -o patch_$(date +'%Y%m%d').zip --
why not create a git patch which you can then apply to the other codebase?
$ git format-patch HEAD^..HEAD
精彩评论