diff --git a/PGBuild/Modules/TestUpgradeXversion.pm b/PGBuild/Modules/TestUpgradeXversion.pm
index a784686..408432d 100644
--- a/PGBuild/Modules/TestUpgradeXversion.pm
+++ b/PGBuild/Modules/TestUpgradeXversion.pm
@@ -51,8 +51,6 @@ sub setup
 	my $conf      = shift;    # ref to the whole config object
 	my $pgsql     = shift;    # postgres build dir
 
-	return if $from_source;
-
 	return if $branch !~ /^(?:HEAD|REL_?\d+(?:_\d+)?_STABLE)$/;
 
 	my $animal = $conf->{animal};
@@ -351,7 +349,16 @@ sub test_upgrade    ## no critic (Subroutines::ProhibitManyArgs)
 	  if $verbose;
 
 	# load helper module from source tree
-	unshift(@INC, "$self->{buildroot}/$this_branch/pgsql/src/test/perl");
+	my $source_tree;
+	if ($from_source)
+	{
+		$source_tree = $self->{pgsql};
+	}
+	else
+	{
+		$source_tree = "$self->{buildroot}/$this_branch/pgsql";
+	}
+	unshift(@INC, "$source_tree/src/test/perl");
 	require PostgreSQL::Test::AdjustUpgrade;
 	PostgreSQL::Test::AdjustUpgrade->import;
 	shift(@INC);
@@ -694,6 +701,11 @@ sub installcheck
 	my $upgrade_loc          = "$upgrade_install_root/$this_branch";
 	my $installdir           = "$upgrade_loc/inst";
 
+	# Don't save in a $from_source build: we want the saved trees always
+	# to correspond to branch tips of the animal's standard repo.  We can
+	# perform upgrade tests against previously-saved trees, though.
+	if (!$from_source)
+	{
 	# for saving we need an exclusive lock.
 	get_lock($self, $this_branch, 1);
 
@@ -716,6 +728,7 @@ sub installcheck
 	  if ($verbose > 1);
 	send_result('XversionUpgradeSave', $status, \@saveout) if $status;
 	$steps_completed .= " XVersionUpgradeSave";
+	}
 
 	# in saveonly mode our work is done
 	return if $ENV{PG_UPGRADE_SAVE_ONLY};
@@ -744,7 +757,7 @@ sub installcheck
 		# other branch from being removed or changed under us.
 		get_lock($self, $oversion, 0);
 
-		$status =
+		my $status =
 		  test_upgrade($self, $save_env, $this_branch, $upgrade_install_root,
 			$dport, $install_loc, $other_branch) ? 0 : 1;
 
