Show HN: Git-Ready to Deploy? Check for uncommitted and non-pushed changes
github.comI wrote a git-tag based cli content deployment tool that does something like this as part of the deploy stage. It's intended for use with multiple users with a single remote, so before attempting to deploy anything it does the following to ensure no conflicts and that outdated content is never accidentally deployed:
- Fetches
- Checks the branch you are deploying from hasn't diverged from it's tracking branch.
- Checks whether each path+tree-object combo trying to be deployed has already been tagged.
- Checks whether each tree path being deployed is clean.
- Finally, if it fails to push new tags it reverts everything to prevent deploys unavailable to everyone else.
I built this for a special type of content deployment for the company I work for but I think it's only been used internally so far (albeit successfully) - I made the tool as generalised as possible though as the core concept is quite re-usable, but I don't think I have described it's purpose clearly enough for the rest of the world in the readme:Do you know about `git-sh-setup`? As in:
. "$(git --exec-path)/git-sh-setup"
require_clean_work_tree "bump" "Please commit or stash them."
https://git-scm.com/docs/git-sh-setupThis will only spot uncommitted changes to tracked files. I want a completely clean repository before I deploy, where there are neither uncommitted changes to tracked files, nor (new) untracked files.
But no, I did not know of git-sh-setup, thanks for the tip :-)
If that's your goal, it might be better to just never deploy from a checked out repository and instead always make a new copy of the code (git clone, git archive, download the tarball from github etc). As in, make the deploy script do that for you, so you never even get into a situation where you could have a dirty working tree in the first place.
You could take it a step further and setup a dead simple server that does it for you and tracks the results in a central place for the whole team. With a manual trigger if you so desired.
CircleCI etc are decent at this.
I'm confused. How is that different from 'git status'?
It first performs a git status, then fetches changes from upstream, and checks if all local changes have been pushed upstream (using git cherry).
I'm curious what the workflow is here.
My workflow looks like this:
A feature branch is mature enough to get merged into master. So I merge it into master on the staging server. And then push it to the public server.
Yes, so this is useful where deployment is "manual" in the sense that it is not a mere git push. It is bad practice to have git data lying around among otherwise public files, so you have to either set up git hooks on the public server, or fine-tune your public server access rights. Both require (slightly) more work than simply not pushing the git data in the first place.
> It is bad practice to have git data lying around among otherwise public files
Usually I have source files in a “src” subdirectory and assets in an “assets” subdirectory and configure the web server to serve from these two subdirectories.
So the git repo root is one level above anything served by the web server.
There are almost no public files on a server these days. It's mostly backend code generating output by combining data from databases and templates. So since it's already all non public stuff, I don't see a problem having the .git folder there too.have git data lying around among otherwise public files
Well, git status doesn’t show unpushed changes from other branches but when I deploy, I normally go into the deployment branch and run git status there. So the unpushed changes in other branches would be quite insignificant.
But everyone’s workflow is different. The author maybe should have added a reason why he uses that instead of git status
Ok, so that would be a difference. Showing all unpushed changes from all branches.
Seems unusual that all branches are involved in deployment though. Isn't the typical workflow that only one branch get's deployed to the user facing machine?
`git status --porcelain` and `if git diff-index --quiet HEAD -- ; then ...` might be lighter/easier ways (and include non-staged files [as well]).
Er, I guess that doesn't tell if you if you have un-pushed changes... but if your deployment process allows someone to deploy without pushing, your process is broken. Someone will deploy to Prod and forget to push their config changes, eventually.
On a somewhat related note, I created check-git a few months ago. It scans a directory tree for unclean git repositories. Maybe someone will find it useful.
Useful. Maven checks that for autpmated deployments. It delegates that part to SCM plugins as far as I know. Wonder if this one does the same as Maven. On mobile, but may check later (tis probably around here https://github.com/apache/maven-scm?files=1)
In my job I've written a small script that compares JIRA entries to what lies into git. This I way I can spot things that were forgotten or put on the wrong branch...
ok, seriously, is "using git push to do a deploy" a thing? WTF?
Absolutely. I can't imagine doing it any other way anymore. https://www.weave.works/blog/gitops-operations-by-pull-reque...
One of the major reasons Kubernetes is a thing is because all of your deployment can be declarative. Deploy-via-Git means I can destroy my entire world and bring it back in a minute or less.
What is the correct way in your opinion?
If you have code that needs to compile, pull in packages, load configuration or for any other reason can't just run in production from a clean checkout, then the proper way is to go through a CI server (teamcity, Jenkins, Travis, etc), and have a script that gets from your clean checkout to a package/zip that runs in production.
I git push to deploy stuff regularly..