0

A large existing PHP project that is having Unit Tests retrofitted to it. I want to have a "tests" directory in the code on the development branch which contains these unit tests and perhaps the DB fixtures also. Naturally I don't want anything in there making its way onto the production environment so I want a way of automatically excluding this directory when it's deployed. Or ideally, a way to avoid anything in there that is committed from being merged into master in the first place.

How do I manage this? There will be frequent and unpredictable commits to the test directory so I can't simply skip certain commits manually.

EDIT: I've now got four answers telling me about .gitignore. I don't believe .gitignore is appropriate here because I want to exclude something that IS to be committed but only from a specific branch.

treyBake
  • 6,440
  • 6
  • 26
  • 57
JaneDoe
  • 430
  • 1
  • 4
  • 16
  • 2
    Have you done any research into excluding directories from git commits? I have a feeling you'd find the answer pretty quickly. – Patrick Q Nov 12 '18 at 14:09
  • 1
    Why do you not want your tests to go along with the code under test? It sounds like you just need to change your deployment process. – Lee Nov 12 '18 at 14:17
  • @PatrickQ Yes. But I only know how to do that with .gitignore or sparse checkouts. Neither of which cover this use case as far as I can see. – JaneDoe Nov 12 '18 at 15:08
  • @Lee I do want my tests to go along with the code. But I don't want it in the master branch. Or else yes, I can change my deployment process but I don't know a way to explicitly exclude a single directory from deployment. – JaneDoe Nov 12 '18 at 15:09
  • 1
    Why don't you want tests in the master branch? Where do you branch from for new features? – Lee Nov 12 '18 at 15:14
  • @Lee Because the master branch is our deployment branch and I don't want our tests folder and fixtures in a production environment. So as I said, I need a way to exclude them from being merged into this branch or a way to blacklist this directory from being deployed. – JaneDoe Nov 13 '18 at 11:06
  • @Lee Following a standard gitflow methodology with a Development and a Master branch. Feature branches are taken from Development. Commits in Development get tagged after testing and merged to Master which is our deployment branch. Development branch has the unit tests in it. Master does not. A hotfix branch may be taken from Master but still gets merged to Development for testing and keeping up to date. – JaneDoe Nov 13 '18 at 11:13
  • As I said, this sounds like a deployment issue and version control is the wrong place to try handle it. – Lee Nov 13 '18 at 12:36
  • So there is no way to exclude something from a merge? I thought there might not be. But in that case, how do I exclude something from being deployed a part of the branch? – JaneDoe Nov 13 '18 at 15:29

3 Answers3

3

it's called .gitignore

From the docs:

A gitignore file specifies intentionally untracked files that Git should ignore. Files already tracked by Git are not affected

source: https://git-scm.com/docs/gitignore

For examples sake, let's say you have this working tree:

|-app
|-test
|-index.php

to exclude test/ the test directory add a .gitignore on the same level as the .git folder and in it just add:

test/

commit the git ignore and make a change/add a file to test/ and you'll notice it doesn't appear when you run

$ git status
treyBake
  • 6,440
  • 6
  • 26
  • 57
  • My understanding of gitignore is that it wouldn't be suitable because I DO want to push these files to the development branch, but not to the master branch. .gitignore is not a per-branch thing, as far as I understand it. Am I wrong? – JaneDoe Nov 12 '18 at 15:07
  • then it's not possible, there is a workaround described here: https://stackoverflow.com/questions/29579546/git-excludesfile-for-a-branch#29583813 – treyBake Nov 12 '18 at 15:14
  • Thanks for the reply. Is this the normal way people exclude a tests folder in a production environment? It seems very ungainly. – JaneDoe Nov 13 '18 at 11:08
  • @JaneDoe personally I'd never have tests on production – treyBake Nov 13 '18 at 11:34
  • Nor would I! That's exactly what my question is - how can I keep tests, which I want to be part of other branches, from being merged into the production branch? – JaneDoe Nov 13 '18 at 15:30
  • @JaneDoe a git ignore.. I wouldn't want it per branch, tests wouldn't be in my repo – treyBake Nov 13 '18 at 15:30
  • But I need the tests in my development repo so that people who take a branch from it get those tests with it and can commit new tests and updates to fixtures which they'll need to do when working on their feature branch. Don't people normally keep their unit tests as part of the code base? – JaneDoe Nov 13 '18 at 15:32
  • @JaneDoe then just zip it and sftp it across? I personally don't but then the question starts turning into opinion – treyBake Nov 13 '18 at 15:36
  • But that's just the same thing again - copying something into a deployed branch. I want them to be part of a branch. My question is if there is a way to prevent part of a branch (i.e. the tests folder) from being merged into a particular branch. – JaneDoe Dec 01 '18 at 17:34
1

I've found that the way to keep a part of a branch from being merged into another branch on a permanent basis is to use sub-modules.

I created my unit tests folder as its own repository and then included it in my mainline branch (which is not the production/master branch) as a sub-module.

https://git-scm.com/book/en/v2/Git-Tools-Submodules

By default when you clone a repository, sub-modules are not cloned with it. The sub-module directory is created but remains empty, unless you also execute

git submodule init
git submodule update

Therefore it's as simple as not including the above commands in your production git clone but including them when you clone the repository for testing or development. You can make any changes to the tests directory along with the codebase and commit both together. This means tests can be developed alongside the code base without risking them being deployed to production.

I found the following aliases useful to set up to streamline git operations:

$ git config alias.sdiff '!'"git diff && git submodule foreach 'git diff'"
$ git config alias.spush 'push --recurse-submodules=on-demand'
$ git config alias.supdate 'submodule update --remote --merge'

This seems to be the correct approach to solving the problem of wanting separation of code in a single repository to be different on a per-branch basis.

JaneDoe
  • 430
  • 1
  • 4
  • 16
0

You can use .gitignore. This is a file in your project root and you can list all files and directories you don't want to commit/push. They are separated by a new line.

Lithilion
  • 1,097
  • 2
  • 11
  • 26
  • Please read my question. I want the files committed to a repo but excluded from a deploy or merge. That's not what gitignore does. – JaneDoe Nov 13 '18 at 11:09