From 76aed6ef732de38d82245b3d674f70bab30221e5 Mon Sep 17 00:00:00 2001 From: Owen Jacobson Date: Fri, 3 Jul 2015 22:31:49 -0400 Subject: Fuck it, serve the files directly. --- .html/git/stop-using-git-pull-to-deploy.html | 178 +++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 .html/git/stop-using-git-pull-to-deploy.html (limited to '.html/git/stop-using-git-pull-to-deploy.html') diff --git a/.html/git/stop-using-git-pull-to-deploy.html b/.html/git/stop-using-git-pull-to-deploy.html new file mode 100644 index 0000000..a3736a0 --- /dev/null +++ b/.html/git/stop-using-git-pull-to-deploy.html @@ -0,0 +1,178 @@ + + + + + The Codex » + Stop Using Git Pull To Deploy + + + + + + + + +
+ + + + + +
+

Stop using git pull for deployment!

+

The problem

+
    +
  • You have a Git repository containing your project.
  • +
  • You want to “deploy” that code when it changes.
  • +
  • You'd rather not download the entire project from scratch for each + deployment.
  • +
+

The antipattern

+

“I know, I'll use git pull in my deployment script!”

+

Stop doing this. Stop teaching other people to do this. It's wrong, and it +will eventually lead to deploying something you didn't want.

+

Deployment should be based on predictable, known versions of your code. +Ideally, every deployable version has a tag (and you deploy exactly that tag), +but even less formal processes, where you deploy a branch tip, should still be +deploying exactly the code designated for release. git pull, however, can +introduce new commits.

+

git pull is a two-step process:

+
    +
  1. Fetch the current branch's designated upstream remote, to obtain all of the + remote's new commits.
  2. +
  3. Merge the current branch's designated upstream branch into the current + branch.
  4. +
+

The merge commit means the actual deployed tree might not be identical to +the intended deployment tree. Local changes (intentional or otherwise) will be +preserved (and merged) into the deployment, for example; once this happens, +the actual deployed commit will never match the intended commit.

+

git pull will approximate the right thing “by accident”: if the current +local branch (generally master) for people using git pull is always clean, +and always tracks the desired deployment branch, then git pull will update +to the intended commit exactly. This is pretty fragile, though; many git +commands can cause the local branch to diverge from its upstream branch, and +once that happens, git pull will always create new commits. You can patch +around the fragility a bit using the --ff-only option, but that only tells +you when your deployment environment has diverged and doesn't fix it.

+

The right pattern

+

Quoting Sitaram Chamarty:

+
+

Here's what we expect from a deployment tool. Note the rule numbers -- +we'll be referring to some of them simply by number later.

+
    +
  1. +

    All files in the branch being deployed should be copied to the + deployment directory.

    +
  2. +
  3. +

    Files that were deleted in the git repo since the last deployment + should get deleted from the deployment directory.

    +
  4. +
  5. +

    Any changes to tracked files in the deployment directory after the + last deployment should be ignored when following rules 1 and 2.

    +

    However, sometimes you might want to detect such changes and abort if +you found any.

    +
  6. +
  7. +

    Untracked files in the deploy directory should be left alone.

    +

    Again, some people might want to detect this and abort the deployment.

    +
  8. +
+
+

Sitaram's own documentation talks about how to accomplish these when +“deploying” straight out of a bare repository. That's unwise (not to mention +impractical) in most cases; deployment should use a dedicated clone of the +canonical repository.

+

I also disagree with point 3, preferring to keep deployment-related changes +outside of tracked files. This makes it much easier to argue that the changes +introduced to configure the project for deployment do not introduce new bugs +or other surprise features.

+

My deployment process, given a dedicated clone at $DEPLOY_TREE, is as +follows:

+
cd "${DEPLOY_TREE}"
+git fetch --all
+git checkout --force "${TARGET}"
+# Following two lines only required if you use submodules
+git submodule sync
+git submodule update --init --recursive
+# Follow with actual deployment steps (run fabric/capistrano/make/etc)
+
+

$TARGET is either a tag name (v1.2.1) or a remote branch name +(origin/master), but could also be a commit hash or anything else Git +recognizes as a revision. This will detach the head of the $DEPLOY_TREE +repository, which is fine as no new changes should be authored in this +repository (so the local branches are irrelevant). The warning Git emits when +HEAD becomes detached is unimportant in this case.

+

The tracked contents of $DEPLOY_TREE will end up identical to the desired +commit, discarding local changes. The pattern above is very similar to what +most continuous integration servers use when building from Git repositories, +for much the same reason.

+
+ + + +
+
+ + +comments powered by Disqus +
+ + + + + +
+ + \ No newline at end of file -- cgit v1.2.3