4

When the git is used for source control, it is recommended to exclude generated code from the version control.

Recently I have learnt that git push to remote repository can be used for deployment purposes.

My question is how to treat source and generated code in git version control. Do I have to keep separate repos for source and for the deployment?

Perhaps there is way to keep both source and generated stuff in one repo and using some git techniques to merge distribution files to lets say deployment branch?

Thank you.

  • Can you please share more information about what you meant saying "`git push` [...] can be used for deployment purposes". What scenario are you referring to? Is it web/mobile/desktop application etc? – Max Komarychev May 19 '16 at 13:53
  • @MaxK I am referring to [this] (https://gist.github.com/thomasfr/9691385) scenario. I tried it myself and it worked very well. – Pavel Novotny May 19 '16 at 14:09
  • Ah, so you already tried `post-receive` - that is good, please see my answer below. – Max Komarychev May 19 '16 at 14:14

2 Answers2

1

The problem with one branch with source files and one branch with generated files is that when you switch from source to generated branch, git will delete the source files, and complain that the generated files have changed.

You can switch branches with out the file problems with low level commands something like this

git-read-tree <deploybranch>
git update-index --refresh
git write-tree
git commit -p <deploybranch> TREESHA
git branch -f <deploybranch> COMMITSHA
git read-tree <reg branch>
git update-index --refresh

but seems too complex for a deployment. You will have to manually enter the SHA values.

Consider putting generated code in a separate deployment repository

set GIT_DIR=<local-deployment-dir> 
git add <local-deployment files>
git commit -m"Release #.##"
git push <remote-deployment-repos> master:master
set GIT_DIR=
Gregg
  • 2,444
  • 1
  • 12
  • 21
  • Thank you for you answer, looks like the separate repository for deployment files is necessary. Then this "deployment" repository can be used to push to remotes (test, prod..). – Pavel Novotny May 19 '16 at 15:08
  • Although this approach may do the job you are abusing source control tool by storing data that is really a part of deployment routine. – Max Komarychev May 19 '16 at 15:33
0

Details may depend on what scenario are you referring to (either this is web/mobile/desktop app or library or whatever). But the general approach is to not keep autogenerated stuff in your repository.

Instead you should consider providing a set of scripts/tools that will allow developers to "unwrap" working environment from clean hand-written sources.

If you want to deliver artifacts of your work to customers by doing git push you may consider using a CI tool where you will script all actions needed to produce deliverable item from sources.

In a simplest approach (if for any reason CI system is not applicable) you can script deployment action in post-receive hook on remote side.

A few references:

githooks manpage

Setting up Push-to-Deploy with git

Should I store generated code in source control


Update

If you chose this way you should think on approach that will allow you to reproduce exact environment from any version in the past. This mostly applies to dependencies - in case of ruby you should commit Gemfile.lock to your repo, in case of node - you should use npm shrinkwrap or similar tool to make sure that you can reproduce exactly the same environment that was used to deliver previous (that could have been released over a year ago and since then you have dozen new versions or your dependencies) version of your app/site or whatever to allow debugging.

Good practice here is to use tags in Git and embed information into deliverable that will allow you to find exact commit that was used to produce it.

Community
  • 1
  • 1
Max Komarychev
  • 2,836
  • 1
  • 21
  • 32
  • Thank you for your answer, but the need for versioning of the distro is exactly the reason I use hooks only for copying from bare repo to deployment folder and starting/stopping the server on remote. – Pavel Novotny May 19 '16 at 14:17
  • I'm sorry, I am not following you on the "versioning", can you please be more specific? I mean for my understanding "version" of a deliverable can be stored in a config file that is used to produce artifacts marked with that version, when you are ready to release - you increment version in this file and push it. Remote reads this file, generates whatever needed for delivery and delivers. Am I missing something? – Max Komarychev May 19 '16 at 14:22
  • For instance my current case is an iOS app with react-native framework, iOS app has a version written in the project file, react-native requires me to generate .js bundle with all the code and embed it into binary. So my CI tool takes new version of code in iOS project, reads dependencies, produces minified .js file which is never kept in the repo and compiles binary that is deployed to customers. At the same time sha1 of a commit is available in the app itself on a special page so I can exactly tell which version I install and tag `vX.Y.Z` is pushed to Git so I can always find commit. – Max Komarychev May 19 '16 at 14:30
  • Do you deploy your `minified.js` using `git push`? In that case it is scenario I am asking about. If so, do you use another repository to hold minified.js just for the purpose of pushing? – Pavel Novotny May 19 '16 at 14:53
  • No and no, `minified.js` is derived from hand-written sources on remote side each time I push. There is no value of keeping generated code in the repo as it may be derived from hand-written code any time you need it. – Max Komarychev May 19 '16 at 15:31
  • There is value of keeping it, but solely for deployment purpose using `git push` to remote repository, and as the feature alone it is really cool thing, in my opinion. My question was, if I have to keep it in another repository, different from source rep, or if I can use the same repository. Using perhaps some clever git techniques, for separating deployment and source between branches. As I understand now, separate repository is the preferred way. – Pavel Novotny May 19 '16 at 16:23
  • Aha, so if you really prefer using git to keep deliverables you may want to read about orphan branches (please refer to docs on git checkout https://git-scm.com/docs/git-checkout). Git allows you to have multiple branches that do not share common commits so that histories are not connected. I am sorry if I misread your original intention. – Max Komarychev May 19 '16 at 18:05