Of course, version control (CVS or subversion) helps, but I don't always want to commit my changes back to the repository. Someday I should also investigate a distributed version control system that lets other users "check out" your branches. However, most of the projects I work on use cvs and svn. I also like to extract the changes that I've made, in order to keep track of my versions by hand. This is useful when I reach milestones in projects, and I want to make off-line backups.
My preferred method is to use diff and patch. When I'm planning to create my own patches, I first copy the original project's directory tree. For example, if the project I'm working on is in a directory called "foo", then from the parent directory of foo I will:
>$ cp -lpr foo foo-new
>$ echo "set backupcopy=auto,breakhardlink" >> ~/.vimrc
>$ diff -uprN foo foo-new > foo-new-1.00.patch>$ ls -la foo-new-1.00.patch
I check the ls output to make sure my patch is a reasonable size. I will also usually open it and make sure it looks right. Then, I can send my patch to someone, or apply it to a copy of foo. I will often test my patch first, for example:
>$ cp -lpr foo foo-test>$ cd foo-test>$ patch -p1 < ../foo-new-1.00.patch
If I am creating a lot of new files, or replacing entire files, I will also just generate tar balls of my entire project. But these can get rather large, and when I really just want the diff, I recently found a way that I can do better.
With tar, I can also just archive the files that have been changed. Then when you untar, only those files are overwritten. The first thing I do is create a "staging area" for the new files in the same parent directory as the foo project:
>$ mkdir foo-stageNext I copy the directory structure (only the directories!) into the staging area, so that I can put new files in the appropriate directories:
>$ cd foo-stageFinally, I will put the new files that I changed in to their appropriate locations in the staging area, and finally I will create a compressed tar (from within foo-stage directory):
>$ (cd ../foo; find -type d ! -name .) | xargs mkdir
>$ tar -zcf ../foo-1.00.tgz .Finally, to apply the tar to a copy,
>$ cp -lpr foo foo-testThe -m option keeps tar from updating the modified timestamps for directories that are unchanged. This will replace files in foo only with the files that I added to foo-stage. This method can also be used in conjunction with diff/patch, in which case I would not use the -N option to diff.
>$ cd foo-test
>$ tar -zxmf ../foo-1.00.tgz
After creating a foo-stage directory and copying the appropriate files into it, the empty directories left over can be a little confusing. The following one-liner will delete the empty directories, leaving only the files that I added:
ReplyDelete> find foo-stage -depth -type d -empty -delete
Enter that from the parent directory of foo-stage.