WooCommerce template overrides live in the theme directory

Editing a file under plugins/woocommerce/templates/ works until the next update overwrites it, which is usually a fortnight. The template loader looks in the active theme first, so a copy placed at yourtheme/woocommerce/ wins and survives upgrades — and that is where the second problem starts, because a copy is a fork.

// woocommerce_get_template() resolves in this order:
//   1. themes/catalogue/woocommerce/loop/price.php
//   2. themes/catalogue/loop/price.php          (older location, still checked)
//   3. plugins/woocommerce/templates/loop/price.php

// but most changes do not need a template at all
add_action( 'woocommerce_after_shop_loop_item_title', 'catalogue_loop_sku', 5 );

function catalogue_loop_sku() {
    global $product;

    if ( $product->sku ) {
        echo '<span class="sku">' . esc_html( $product->sku ) . '</span>';
    }
}

// and removing something upstream added is one line, not a copied file
remove_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart', 10 );

An override stops receiving upstream changes and says nothing about it. A shop that has been through three WooCommerce releases with four copied templates is rendering the markup of whichever version each one was taken from, and the symptom is a feature that “does not work in our theme” when in fact the template predates it. So the order of preference is: use the hooks, which are actions with documented priorities and cover most of what people copy templates for; use a filter where one exists; copy a template only when the markup itself has to change. When you do copy one, put the WooCommerce version it came from in a comment at the top of the file, because nothing in the system will tell you it has drifted and the diff against a newer plugin copy is the only way to find out. That comment is thirty seconds now and an afternoon saved at the next major upgrade.