Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Push to a remote origin on a subfolder of git repository?

I have a git repository which uses Vagrant to build a virtual server for a WordPress project (local development only). The folder structure is roughly as follows (for the purposes of the question).

- Vagrantfile
- puppet/
- wordpress/
    - {www public folder / root Wordpress files}
- files/

Now all these files are in the root of my repository and I would like them to stay there so if I need to add any updates to Vagrant they will be added to the repo. Now my host has the ability to allow me to deploy to my staging and production servers by pushing updates directly using git. But these files are stored in /wordpress/ and the origin on their server is the root. Ideally I would like to push only from the /wordpress/ folder to the root of the remote origin.

I thought of moving the /wordpress/ folder to the root of the project but then all the Vagrant files will be pushed to the production server (unless there is a way to add a .gitignore specific to remote origins).

I am sure there are a few ways to accomplish this, I also looked at git subtrees but it looked like a bit of overkill for this specific issue. If anyone could suggest the best solution it would be appreciated.

like image 720
alexmcfarlane Avatar asked Mar 21 '23 12:03

alexmcfarlane


1 Answers

The indirect, and snotty answer, is that git isn't a deployment tool. So you should use phing, or capistrano, or ant, or puppet, or chef, or ansible, or grunt, or just write some bash script, etc.

The short answer is git-subtree split. I'll go with this.

The Explanation

Subtree, even more so that submodules, can be confusing if you don't really know what's going on. Normally they are used for modular development as an alternative to submdodules. I won't go into that because thats not how you would use it in this case.

For your purposes, you would perform whats called a subtree split to create a branch that contains only the directory you want. The subtree split command looks through all your repository's history for commits that effect files in a given directory and separates them from changes that don't. You're then able to put those commits (or a squashed version of them) to their own branch. As a consequence, when you checkout that branch, the given directory will be at the root, and nothing else.

Nuts and Bolts

I'm going to make some choices for you in my explanation, but you're free to change those. I'm designating the deploy branch, and I'm deciding to squash your subtree history into a single commit since you should never use that branch to do any development. I'm also assuming your repository name is origin.

git subtree split --prefix=wordpress --squash --branch deploy
git push -f origin deploy:deploy

By pushing with the deploy:deploy notation, you dont actually have to checkout the deploy branch (which might take time to do) in order to push it. You could actually avoid even creating the branch all together by just pushing to the remote branch directly.

git subtree push --prefix=wordpress --squash deploy master

I recommend using this last method, since it avoids accidentally doing anything with the squashed subtree branch.

But,... subtree doesnt work for me because XYZ

Yeah, subtree splitting is still spotty sometimes. If for whatever reason the subtree command isn't an option for you, thats ok. You can use the older, even more confusing git-filter-branch command. See here for a full explanation on that command.

If your stuck with this choice, then.. that stinks. You're probably better off just using submodules (probably the way to go if your at this point), or writing some bash script to copy files to a different repo on you local and pushing... or something else terrible.

Or you could just use a real deployment tool.

like image 196
eddiemoya Avatar answered Mar 23 '23 09:03

eddiemoya