Roots Discourse

How to update Trellis?

Hey everyone, it seems there have been some improvements in the Trellis repo. However I can’t see anywhere in the docs how to update to the latest version? Previous discussions of this topic seem to be quite old so what is currently the correct way?

Thanks,
Kris

We do need some docs on the process but this seems to be the be thread on it: Best practices to update Trellis

There’s a few strategies and discussion.

1 Like

Not sure what your level of Git understanding is. Mine is scraping the bottom :slight_smile:
@chrisk2020 wrote a helpful article here: Working with Git Subtrees And Trellis
I was struggling with this, but then noticed I needed to use

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

in order to merge, because of a newer git version.

This git subtree merging page sure helped wrap my head around this. A bit…

1 Like

So I decided not to use subtrees after playing around with them, but I did want to be able to update on a regular basis and preferably in a way that wasn’t very complex.

Here’s what I do now for both Trellis and Bedrock:

git checkout -b upgrade
git clone --depth=1 #{repo} upgrade
rm -rf upgrade/.git
rsync -ah --progress upgrade/ #{dest}
rm -rf upgrade

What this lets me do is review any changes made to the remote repo, merge in any changes that don’t overwrite my local updates, and then update the dependency with a single commit.

I threw this into a Makefile, and it really helps me just to merge it each time I do a bit of work on my site to just update each. But after a while, I grew frustrated with Make – I’m really not an expert at it – and converted it into a Rakefile. But that then had the problem that I wanted to continue developing the Rakefile and apply the changes to all the sites I worked on, so I had to solve that problem too.

Feel free to check out the repo that I created with my attempt to solve the problem, though it still needs a bit more love.

1 Like

@robyurkowski’s repo is no longer there. I got a 404 anyways.

Ah, sorry! I turned it private a while back while I wasn’t able to maintain it. It’s back public now… There are still a handful of issues with it but it should be a good starting point and patches are always welcome. :slight_smile:

2 Likes

For updating trellis is #{dest} supposed to be “trellis”?

I suppose it depends on where you’re calling it from. If you have a pretty typical directory structure (root folder with trellis/, bedrock/) and you want to update trellis, do something like this:

cd trellis

# Create a new git branch called 'upgrade'
git checkout -b upgrade 

# Check out a flat-packed trellis repo into the upgrade/ directory
git clone --depth=1 https://github.com/roots/trellis.git upgrade

# Trash the git folder of the repo we just downloaded since 
# we don't care about trellis's history, just our own app's history
rm -rf upgrade/.git 

# Copy all files over from the upgrade directory to the
# trellis directory (which we're in)
rsync -ah --progress upgrade/ ./

# Remove the now-mostly-empty upgrade dir
rm -rf upgrade

# See what's changed
git status

These days, I do a trellis site about every three months, and because I’m not always working with it, I’ve really tried to encapsulate my workflow into a ruby script that likewise gets copied into the root of the repository and updated in the same way.

Because I do this task for three different subrepositories, I extracted it into a little method:

def branch_and_sync(repo:, dest:)
  `git checkout -b upgrade`
  `git clone --depth=1 #{repo} upgrade`
  `rm -rf upgrade/.git`
  `rsync -ah --progress upgrade/ #{dest}`
  `rm -rf upgrade`

  header "Now review the changes, discarding any that might overwrite your own local changes.\n\nAfterward, commit the changes and merge into master. Then delete the update branch."
end

And those get called as such:

SITE_NAME       = "example.com".freeze
SITE_NAME_DEV   = SITE_NAME.split(".")[0..-2].join(".") + ".dev"
ROOT_PATH       = File.expand_path("../", __FILE__)
TRELLIS_FOLDER  = File.join(ROOT_PATH, "provision")
BEDROCK_FOLDER  = File.join(ROOT_PATH, "site")
REMOTE_APP_FOLDER = "/srv/www/#{SITE_NAME}/current/"

BASE_REPO       = "git@github.com:robyurkowski/trellis-template.git"
TRELLIS_REPO    = "https://github.com/roots/trellis.git"
BEDROCK_REPO    = "https://github.com/roots/bedrock.git"

namespace :update do
  desc "Updates trellis."
  task :trellis do
    branch_and_sync(repo: TRELLIS_REPO, dest: TRELLIS_FOLDER)
  end

  desc "Updates bedrock."
  task :bedrock do
    branch_and_sync(repo: BEDROCK_REPO, dest: BEDROCK_FOLDER)
  end

  desc "Updates base rakefile."
  task :base do
    branch_and_sync(repo: BASE_REPO, dest: ROOT_PATH)
  end
end

Hope that provides enough clarity for you and others in the future!

Thank you very much. This makes much more sense now. For the git status step, are you saying just selectively stage files based on memory? Or is there a way to do a diff? I’m pretty much a beginner at git.

The best way to do it from the command line is to use git add -p, which will let you select chunks of files to stage. There is also the corresponding git checkout -p which lets you remove changes from files.

1 Like