Best practices to update Trellis

I ran into the same error today. I was on an existing project where the subtrees had not been setup from the get go and various commits had already taken place.

if you skip the read-tree command and instead do git merge -X subtree=trellis/ --squash trellis/master it should work ok - there should be merge conflicts that represent your local changes. resolve these and you should be good. I’ve not had much chance to test, but it seemed to work fine for me.

1 Like

Thanks. I have another stupid question…How do I resolve the conflicts? This is the first time I’ve done anything other than commit changes to git. I type git status and see the files but how do I tell it what to leave and what to change?

Macintosh-2:nationalsafetystanddown.com Tom$ git merge -X subtree=trellis/ --squash trellis/master
Removing trellis/vars/sudoer_passwords.yml
Auto-merging trellis/roles/wordpress-setup/templates/wordpress-site.conf.j2
CONFLICT (content): Merge conflict in trellis/roles/wordpress-setup/templates/wordpress-site.conf.j2
Auto-merging trellis/roles/php/tasks/main.yml
CONFLICT (content): Merge conflict in trellis/roles/php/tasks/main.yml
CONFLICT (modify/delete): trellis/roles/composer/tasks/main.yml deleted in trellis/master and modified in HEAD. Version HEAD of trellis/roles/composer/tasks/main.yml left in tree.
Auto-merging trellis/requirements.yml
CONFLICT (content): Merge conflict in trellis/requirements.yml
Auto-merging trellis/hosts/staging
CONFLICT (content): Merge conflict in trellis/hosts/staging
Auto-merging trellis/hosts/production
CONFLICT (content): Merge conflict in trellis/hosts/production
Auto-merging trellis/group_vars/staging/wordpress_sites.yml
CONFLICT (add/add): Merge conflict in trellis/group_vars/staging/wordpress_sites.yml
Auto-merging trellis/group_vars/staging/vault.yml
CONFLICT (add/add): Merge conflict in trellis/group_vars/staging/vault.yml
Auto-merging trellis/group_vars/production/wordpress_sites.yml
CONFLICT (add/add): Merge conflict in trellis/group_vars/production/wordpress_sites.yml
Auto-merging trellis/group_vars/production/vault.yml
CONFLICT (add/add): Merge conflict in trellis/group_vars/production/vault.yml
Auto-merging trellis/group_vars/development/wordpress_sites.yml
CONFLICT (add/add): Merge conflict in trellis/group_vars/development/wordpress_sites.yml
Auto-merging trellis/group_vars/development/vault.yml
CONFLICT (add/add): Merge conflict in trellis/group_vars/development/vault.yml
Auto-merging trellis/group_vars/all/users.yml
CONFLICT (add/add): Merge conflict in trellis/group_vars/all/users.yml
Auto-merging trellis/group_vars/all/main.yml
CONFLICT (add/add): Merge conflict in trellis/group_vars/all/main.yml
Auto-merging trellis/deploy-hooks/build-before.yml
CONFLICT (add/add): Merge conflict in trellis/deploy-hooks/build-before.yml
Auto-merging trellis/Vagrantfile
CONFLICT (content): Merge conflict in trellis/Vagrantfile
Auto-merging trellis/README.md
CONFLICT (content): Merge conflict in trellis/README.md
Auto-merging trellis/CHANGELOG.md
CONFLICT (content): Merge conflict in trellis/CHANGELOG.md
Squash commit – not updating HEAD
Automatic merge failed; fix conflicts and then commit the result.
Macintosh-2:nationalsafetystanddown.com Tom$ git status
On branch master
Your branch is up-to-date with ‘origin/master’.
Changes to be committed:
(use “git reset HEAD …” to unstage)

modified:   trellis/.editorconfig
modified:   trellis/.gitignore
modified:   trellis/.travis.yml
new file:   trellis/filter_plugins/trellis_filters.py
deleted:    trellis/vars/sudoer_passwords.yml

Unmerged paths:
(use “git reset HEAD …” to unstage)
(use “git add/rm …” as appropriate to mark resolution)

both modified:   trellis/CHANGELOG.md
both modified:   trellis/README.md
both modified:   trellis/Vagrantfile
both added:      trellis/deploy-hooks/build-before.yml
both added:      trellis/group_vars/all/main.yml
both added:      trellis/group_vars/all/users.yml
both added:      trellis/group_vars/development/vault.yml
both added:      trellis/group_vars/development/wordpress_sites.yml
both added:      trellis/group_vars/production/vault.yml
both added:      trellis/group_vars/production/wordpress_sites.yml
both added:      trellis/group_vars/staging/vault.yml
both added:      trellis/group_vars/staging/wordpress_sites.yml
both modified:   trellis/hosts/production
both modified:   trellis/hosts/staging
both modified:   trellis/requirements.yml
deleted by them: trellis/roles/composer/tasks/main.yml
both modified:   trellis/roles/php/tasks/main.yml
both modified:   trellis/roles/wordpress-setup/templates/wordpress-site.conf.j2

@tinytoolbox I know this is not a specific answer to your question, but you may want to get started with an OS X app for doing this kind work. I learned so much with Tower and Kaleidoscope, but SourceTree is a good free start at it (and multi-platform too).

4 Likes

Yeah - how to use git - is a little bit out of my scope here. The list of files look like I’d suspect. You’ll see inside each conflicted file something like

<<<<<<< head
something from your repo here
==========
<<<<<<<<trellis/master
something new - or from the other branch here
==========

you replace the one you don’t want to keep with the one you do - therefore resolving the conflict. Then add and commit. and that should be that.

Hope that helps a bit.

1 Like

Thanks again Chris. I really appreciate it. I googled how to resolve git conflicts and nothing explained it that simply. I really am just faking this whole “developer” thing. Luckily I’m just working for myself. Cheers!

Thanks. I ended up getting a trial version of Tower and using the comparison tool to resolve my conflicts. MY BEDROCK/TRELLIS SETUP IS WORKING!!! Yay!!!

1 Like

@tinytoolbox That’s great news.

Currently, I keep ‘trellis’ & ‘site’ (bedrock + theme) in different git repositories as it was easier for me to merge changes with Tower when the two are separated. My two next big steps are figuring out how to use Cherry Picking and, more importantly, getting each project into one repository and using git Subtrees with the git merge commands from @chrisk2020.

Edit: I now have everything in one repository…much nicer. The GUIs of Tower and SourceTree cannot be easily be used for the subtree git merge. Use the CLI instead.

1 Like

In my case I had to remove the trailing slash after subtree=trellis, otherwise it gave the error: fatal: entry not found in tree

Apart from that, so far the method seems to work fine. Thanks for the article @chrisk2020

you definitely want a good diff app and Kaleidoscope is quite good. easy on the eyes. kdiff3 is your free alternative. any other means of resolving a messy merge is insanity.

1 Like

I haven’t tried this approach yet so I haven’t yet had to deal with merge conflicts, etc. But with this subtree approach is it possible to rebase instead of merge? The idea would be to rebase the entire Trellis/Bedrock/Sage repos with their updates and then apply all your app specific changes on top of those changes. It might help minimize conflicts? Does that conceptually make sense?

1 Like

FYI - if anyone is using this method and getting this error message:

fatal: refusing to merge unrelated histories

it’s because the default changed in git 2.9; see this SO question.

Add --allow-unrelated-histories to make the command work again:

git merge -X subtree=trellis/ --squash trellis/master --allow-unrelated-histories 

:slight_smile:

10 Likes

Has anyone tried git subtree for this? I just updated my project to use this by doing the following:

git remote add trellis https://github.com/roots/trellis.git
mv trellis trellis-old
git commit -a -m 'Moved trellis to prepare for new subtree setup'
git subtree add --prefix=trellis trellis master --squash

Now trellis is at trellis/ via the git subtree feature, which will be helpful later…

But first you have to copy over all your modifications to trellis from trellis-old.

git diff-tree -r -p HEAD:trellis HEAD:trellis-old

will show you what has changed.

git diff-tree -r -p HEAD:trellis HEAD:trellis-old --name-status

will give you a list of changed files. Decide which ones you actually changed vs. what may have changed in the trellis master. I used my text editor to assemble a list of files I actually wanted to copy in ~/tmp/script.sh, then ran it.

bash ~/tmp/script.sh
git add .
git commit -a -m 'Copied trellis customizations from trellis-old folder'

Then cleanup

rm -rf trellis-old
git commit -a -m 'Removed old trellis dir'

Later, if you want to see how your trellis differs from the latest main branch,

git fetch trellis master
git diff trellis/master HEAD:trellis --name-status

And the coup de grace, when you want to do an update, it’s as easy as:

git subtree pull --prefix=trellis trellis master --squash
17 Likes

Firstly, thank you for the detailed process.
I ran through it and it all works, but was a little confused by:

It might be helpful to include example contents for that bash script.

Instead what I did was at the point of comparison, opened up Kaleidoscope and opened the new trellis folder and the trellis-old folder and managed the changes / copying like that (leaving the trellis-old folder untouched and only moving things to the trellis folder).

Tested the remaining commands and they worked perfectly.

1 Like

Following your instructions, I successfully reorganized an existing Trellis setup to use Trellis in a subtree.
It went fine, except that when I vagrant up , I get an error:

$> vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Checking if box 'bento/ubuntu-16.04' is up to date...
A VirtualBox machine with the name 'domain.loc' already exists.
Please use another name or delete the machine with the existing
name, and try again.

Do I actually need to destroy and recreate the vagrant box every time I update Trellis ?

I simply cloned the trellis repository and left it a normal git repository.
The sites are stored outside, one directory up or even somewhere else (paths can be adjusted).
I pull new changes from the official GitHub trellis repository into my own branch, merging is usually quite easy. Afterwards I test on a fresh staging instance, deploying the sites, then I apply also on production.

2 Likes

I’ve set subtrees for all three. Trellis, Sage and Bedrock.
I finally wanted to update Bedrock as a test. However I can’t get past the merge. This is how it all hapens…

git checkout bedrock

git pull

git checkout master

git merge -X subtree=site/ --squash bedrock/master --allow-unrelated-histories
error: Merging is not possible because you have unmerged files.
hint: Fix them up in the work tree, and then use 'git add/rm '
hint: as appropriate to mark resolution and make a commit.
fatal: Exiting because of an unresolved conflict.

I have only done VERY basic Git commands in the past and have read a good amount on the subject. I just haven’t retained what I’ve read :slight_smile:

The conflict comes from my .gitignore file conflicting with Bedrocks. As, for reasons I don’t understand, all of Bedrock’s files are on the root folder and haven’t been moved to site/ as when git read-tree is used…

Anybody with a bigger Git memory bank make sense of this? I’m happy to read any and all links.

Hi - apologies for the delay - sounds like you just needed to commit the gitignore before trying the update?

1 Like

I don’t recall how I managed it. But thanks thanks for the reply. Thanks for that post, by the way. Very helpful!

Tower is now also available for Windows too.

1 Like

I have had this setup for some time now, but the issue is during updates my changes are basically completely overwritten instead of properly merged. Any ideas?