0

How to make tar archive from git repository since selected commit?

This question is similar to Git archive all changes except first commit but I need .tar archive as a result not git patch file.

Explanation: I make "modules" for a strange PHP CMS where there is no real mechanism for writing extensions. To ship my modules I have to send only the modified files to clients, while I still have to have all CMS files under Git (all added only in first commit).

Community
  • 1
  • 1
jmarceli
  • 19,102
  • 6
  • 69
  • 67
  • This doesn't make sense. What are you trying to archive? If all you want is to get the current state of your working directory in tar form, you can simply use [`git archive`](http://stackoverflow.com/q/160608/456814) for that. If you want to get a patch of changes since a specific commit, you can just do a diff, output it to a file, and then tar up the file. **What are you trying to do?** –  Jun 12 '14 at 14:53
  • I'm trying to make tar archive only with files changed since first commit. – jmarceli Jun 12 '14 at 15:15
  • That's still not clear. So you don't want diff patches, correct? You just want the whole files themselves? You don't mind not including files in the tar archive if they haven't changed? –  Jun 12 '14 at 15:16
  • I want something like: `tar -cvf myarch.tar $(git diff --name-only SHA_OF_COMMIT)` I was hoping that `git archive sth..` will be easier way to do this. – jmarceli Jun 12 '14 at 17:16
  • `git archive` is for extracting the contents of a *single* commit. If you want to copy a sequence of commits/branches/etc. around, `git bundle` is what you want. – twalberg Jun 12 '14 at 18:06

2 Answers2

1

So, the recipient of this archive doesn't have the repo but does have the content of some commit, and you're sending replacements he can untar onto that?

It seems git archive's --output option on windows fails at telling the compressor about the redirection, which duly refuses to write compressed output to what it thinks is a terminal, but that's easily worked around:

git archive -o update-old-new.tgz newcommit \
         $(git diff --name-only --diff-filter=AM oldcommit..newcommit) | cat

That | cat at the end is the workaround.

I'd forgotten about archive, but using it means you don't have to checkout $newcommit first so this is much better than the earlier checkout;diff|tar combo.

Still, this can't handle an update large enough to blow command-line limits, or spaces or other annoying characters in the pathnames. The fallback is

git checkout newversion
git diff --name-only --diff-filter=AM oldversion.. \
| tar Tczf - update-old-new.tgz
jthill
  • 55,082
  • 5
  • 77
  • 137
  • Yeah you got it right that is my problem. The recipients doesn't have GIT and they would like to receive only changed files. – jmarceli Jun 12 '14 at 17:19
0

Run this at the top level of your folders:

tar cvfz files-changed.tgz  `git diff <newrev> <oldrev> --stat --name-only `

e.g

tar cvfz files-changed.tgz  `git diff HEAD HEAD~3 --stat --name-only `
FractalSpace
  • 5,577
  • 3
  • 42
  • 47
  • If he's not on the commit his client's trying to update to, this will archive the wrong file versions. – jthill Jun 12 '14 at 17:48
  • The version 'client is trying to upgrade' would be the 'newrev' in this case. – FractalSpace Jun 13 '14 at 18:31
  • ... and the files that got packed up would be whatever versions are currently checked out, not the versions as of newrev. – jthill Jun 13 '14 at 19:12