Everyone knows the benefits of git. Many developers are using common commands like pull, push, commit, merge, fetch. But Git does also have tools for your deployment strategy.
Deployment
Software deployment is all of the activities that make a software system available for use. (Wikipedia)
In other words: we want to publish changes from our development server to our production or staging server.
Strategy
We want to use git for our three step deployment strategy.
- create an archive with all changes from a specific date
- upload our archive to our production server
- extract and publish our changes on production server
Create update archive
git archive -o archive.zip
This command creates an archive containing all files from our current branch. But we want to get all latest changes from a specific date.
Get all changes of a commit, branch, or another reference
git diff --name-only HEAD
We get a lis of all changes of our last commit.
/.gitignore
/src/Application.php
/tests/ApplicationTest.php
But we need all changes since a specific date until now. Therefore we use git reference HEAD
and passing a date HEAD@{"2016-01-15 00:00:00"}
.
Tip
We could also pass a statement like for a specific moment:
- one day ago
HEAD@{"1 day ago"}
- eight days ago
HEAD@{"8 days ago"}
- one week ago
HEAD@{"1 week ago"}
- five weeks ago
HEAD@{"5 weeks ago"}
- one month ago
HEAD@{"1 month ago"}
Get a list of all changes from a specific date, related to head reference.
git diff --name-only HEAD@{"2016-01-15 00:00:00"}
We need a filtered list of all files except deleted file For our deployment. Adding --diff-filter
:
git diff --name-only HEAD@{"2016-01-15 00:00:00"} --diff-filter=ACMRTUXB
git diff
--diff-filter=[(A|C|D|M|R|T|U|X|B)…[*]]
Select only files that are Added (A), Copied (C), Deleted (D), Modified (M), Renamed (R), have their type (i.e. regular file, symlink, submodule, …) changed (T), are Unmerged (U), are Unknown (X), or have had their pairing Broken (B). Any combination of the filter characters (including none) can be used. When * (All-or-none) is added to the combination, all paths are selected if there is any file that matches other criteria in the comparison; if there is no file that matches other criteria, nothing is selected.
create an archive with changes from a specific date
Pass our change list as subcommand $()
:
git archive -o update.zip HEAD $(git diff --name-only HEAD@{"2016-01-15 00:00:00"} --diff-filter=ACMRTUXB)
Enhanced commands
Archive with branch name and datetime
git archive -o update-$(git rev-parse --abbrev-ref HEAD)-$(date +%Y%m%d-%H%M%S).zip HEAD $(git diff --name-only HEAD@{"2016-01-15 00:00:00"} --diff-filter=ACMRTUXB)
Archive with branch name and datetime for scrumteams (deployment every two weeks)
git archive -o update-$(git rev-parse --abbrev-ref HEAD)-$(date +%Y%m%d-%H%M%S).zip HEAD $(git diff --name-only HEAD@{"2 weeks ago"} --diff-filter=ACMRTUXB)
txt file with all changes, including deleted
git diff --name-status HEAD@{"2016-01-15 00:00:00"} > updates-$(git rev-parse --abbrev-ref HEAD)-$(date +%Y%m%d-%H%M%S).txt
txt file with all changes, excluding deleted
git diff --name-status HEAD@{"2016-01-15 00:00:00"} --diff-filter=ACMRTUXB > updates-$(git rev-parse --abbrev-ref HEAD)-$(date +%Y%m%d-%H%M%S).txt
txt file with all deleted files
git diff --name-status HEAD@{"2016-01-15 00:00:00"} --diff-filter=D > deleted-$(git rev-parse --abbrev-ref HEAD)-$(date +%Y%m%d-%H%M%S).txt
Conclusion
This small tool is helping small teams to provide a manual deployment strategy for bugfixes and hotfixes or sprint deployment. You could combine this commands with unit testing. This is very helpful for emergency deployments, especially when your ci is not available!