diff --git a/cmd/flux/main.go b/cmd/flux/main.go
index 3ef4abacce28ad4de6c92d0a985d548bb0c19c24..9295e83ea3ea7eb6daf56a62d46e666a44c10497 100644
--- a/cmd/flux/main.go
+++ b/cmd/flux/main.go
@@ -25,7 +25,6 @@ import (
 	"github.com/spf13/cobra"
 	_ "k8s.io/client-go/plugin/pkg/client/auth"
 
-	"github.com/fluxcd/flux2/internal/utils"
 	"github.com/fluxcd/flux2/pkg/manifestgen/install"
 )
 
@@ -127,18 +126,6 @@ func NewRootFlags() rootFlags {
 	return rf
 }
 
-type rootContext struct {
-	kubeManager utils.KubeManager
-}
-
-var rootCtx = NewRootContext()
-
-func NewRootContext() rootContext {
-	var rc rootContext
-	rc.kubeManager = utils.DefaultKubeManager()
-	return rc
-}
-
 func main() {
 	log.SetFlags(0)
 	configureKubeconfig()
diff --git a/cmd/flux/main_e2e_test.go b/cmd/flux/main_e2e_test.go
index 23f06f041dcf36f2bc184d173177c4eb8ab56e51..8851f19c3421ca97a3fd150747d2f42685dcb98c 100644
--- a/cmd/flux/main_e2e_test.go
+++ b/cmd/flux/main_e2e_test.go
@@ -15,12 +15,12 @@ func TestMain(m *testing.M) {
 	// Ensure tests print consistent timestamps regardless of timezone
 	os.Setenv("TZ", "UTC")
 
-	// Install Flux
-	km, err := NewTestEnvKubeManager(ExistingClusterMode)
+	// Install Flux.
+	// Creating the test env manager sets rootArgs client flags
+	_, err := NewTestEnvKubeManager(ExistingClusterMode)
 	if err != nil {
 		panic(fmt.Errorf("error creating kube manager: '%w'", err))
 	}
-	rootCtx.kubeManager = km
 	output, err := executeCommand("install --components-extra=image-reflector-controller,image-automation-controller")
 	if err != nil {
 		panic(fmt.Errorf("install falied: %s error:'%w'", output, err))
diff --git a/cmd/flux/main_test.go b/cmd/flux/main_test.go
index 0f4df3b7a493cab6d07b26fdefc1a30c844e0027..70ab23a2bce645f24bad4b20e2732b8d8fab3e4a 100644
--- a/cmd/flux/main_test.go
+++ b/cmd/flux/main_test.go
@@ -13,23 +13,21 @@ import (
 	"text/template"
 	"time"
 
-	"github.com/fluxcd/flux2/internal/utils"
 	"github.com/google/go-cmp/cmp"
 	"github.com/mattn/go-shellwords"
 	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
 	k8syaml "k8s.io/apimachinery/pkg/util/yaml"
 	"k8s.io/client-go/tools/clientcmd"
 	"sigs.k8s.io/controller-runtime/pkg/client"
-	fakeclient "sigs.k8s.io/controller-runtime/pkg/client/fake"
 	"sigs.k8s.io/controller-runtime/pkg/envtest"
 )
 
-func readYamlObjects(objectFile string) ([]client.Object, error) {
+func readYamlObjects(objectFile string) ([]unstructured.Unstructured, error) {
 	obj, err := os.ReadFile(objectFile)
 	if err != nil {
 		return nil, err
 	}
-	objects := []client.Object{}
+	objects := []unstructured.Unstructured{}
 	reader := k8syaml.NewYAMLReader(bufio.NewReader(bytes.NewReader(obj)))
 	for {
 		doc, err := reader.Read()
@@ -44,7 +42,7 @@ func readYamlObjects(objectFile string) ([]client.Object, error) {
 		if err != nil {
 			return nil, err
 		}
-		objects = append(objects, unstructuredObj)
+		objects = append(objects, *unstructuredObj)
 	}
 	return objects, nil
 }
@@ -59,9 +57,18 @@ func (m *testEnvKubeManager) NewClient(kubeconfig string, kubecontext string) (c
 	return m.client, nil
 }
 
-func (m *testEnvKubeManager) CreateObjects(clientObjects []client.Object) error {
+func (m *testEnvKubeManager) CreateObjects(clientObjects []unstructured.Unstructured) error {
 	for _, obj := range clientObjects {
-		err := m.client.Create(context.Background(), obj)
+		// First create the object then set its status if present in the
+		// yaml file. Make a copy first since creating an object may overwrite
+		// the status.
+		createObj := obj.DeepCopy()
+		err := m.client.Create(context.Background(), createObj)
+		if err != nil {
+			return err
+		}
+		obj.SetResourceVersion(createObj.GetResourceVersion())
+		err = m.client.Status().Update(context.Background(), &obj)
 		if err != nil {
 			return err
 		}
@@ -78,15 +85,11 @@ func (m *testEnvKubeManager) Stop() error {
 
 func NewTestEnvKubeManager(testClusterMode TestClusterMode) (*testEnvKubeManager, error) {
 	switch testClusterMode {
-	case FakeClusterMode:
-		c := fakeclient.NewClientBuilder().WithScheme(utils.NewScheme()).Build()
-		return &testEnvKubeManager{
-			client: c,
-		}, nil
 	case TestEnvClusterMode:
 		useExistingCluster := false
 		testEnv := &envtest.Environment{
 			UseExistingCluster: &useExistingCluster,
+			CRDDirectoryPaths:  []string{"manifests"},
 		}
 		cfg, err := testEnv.Start()
 		if err != nil {
@@ -150,8 +153,7 @@ func NewTestEnvKubeManager(testClusterMode TestClusterMode) (*testEnvKubeManager
 type TestClusterMode int
 
 const (
-	FakeClusterMode = TestClusterMode(iota + 1)
-	TestEnvClusterMode
+	TestEnvClusterMode = TestClusterMode(iota + 1)
 	ExistingClusterMode
 )
 
@@ -181,7 +183,6 @@ func (cmd *cmdTestCase) runTestCmd(t *testing.T) {
 	}
 
 	if km != nil {
-		rootCtx.kubeManager = km
 		defer km.Stop()
 	}
 
diff --git a/cmd/flux/testdata/trace/deployment.yaml b/cmd/flux/testdata/trace/deployment.yaml
index 74fc5e46223ffbe49d6b379e624700566d762c05..b1eeb019d667ece14c57cbe0b9c4627c2dd7e6a6 100644
--- a/cmd/flux/testdata/trace/deployment.yaml
+++ b/cmd/flux/testdata/trace/deployment.yaml
@@ -1,8 +1,19 @@
 ---
+apiVersion: v1
+kind: Namespace
+metadata:
+  name: flux-system
+---
+apiVersion: v1
+kind: Namespace
+metadata:
+  name: podinfo
+---
 apiVersion: apps/v1
 kind: Deployment
 metadata:
   labels:
+    app.kubernetes.io/name: podinfo
     app.kubernetes.io/managed-by: Helm
     app.kubernetes.io/name: podinfo
     helm.toolkit.fluxcd.io/name: podinfo
@@ -11,11 +22,18 @@ metadata:
   namespace: podinfo
 spec:
   replicas: 1
+  selector:
+    matchLabels:
+      app.kubernetes.io/name: podinfo
   template:
     metadata:
       labels:
         app.kubernetes.io/name: podinfo
     spec:
+      containers:
+      - name: hello
+        command: [ "echo hello world" ]
+        image: busybox
 ---
 apiVersion: helm.toolkit.fluxcd.io/v2beta1
 kind: HelmRelease
@@ -33,6 +51,7 @@ spec:
         kind: HelmRepository
         name: podinfo
         namespace: flux-system
+  interval: 5m
 status:
   conditions:
   - lastTransitionTime: "2021-07-16T15:42:20Z"
@@ -56,11 +75,14 @@ spec:
     kind: HelmRepository
     name: podinfo
   version: 6.0.0
+  interval: 5m
 status:
   artifact:
     checksum: cf13ba96773d9a879cd052c86e73199b3f96c854
     lastUpdateTime: "2021-08-01T04:42:55Z"
     revision: 6.0.0
+    path: "example"
+    url: "example"
   conditions:
   - lastTransitionTime: "2021-07-16T15:32:09Z"
     message: 'Fetched revision: 6.0.0'
@@ -86,6 +108,8 @@ status:
     checksum: 8411f23d07d3701f0e96e7d9e503b7936d7e1d56
     lastUpdateTime: "2021-07-11T00:25:46Z"
     revision: 8411f23d07d3701f0e96e7d9e503b7936d7e1d56
+    path: "example"
+    url: "example"
   conditions:
   - lastTransitionTime: "2021-07-11T00:25:46Z"
     message: 'Fetched revision: 8411f23d07d3701f0e96e7d9e503b7936d7e1d56'
@@ -104,6 +128,8 @@ spec:
     kind: GitRepository
     name: flux-system
   validation: client
+  interval: 5m
+  prune: true
 status:
   conditions:
   - lastTransitionTime: "2021-08-01T04:52:56Z"
@@ -126,4 +152,5 @@ spec:
     branch: main
   secretRef:
     name: flux-system
-
+  interval: 5m
+  url: ssh://git@github.com/example/repo
diff --git a/cmd/flux/testdata/trace/helmrelease-missing-git-ref.txt b/cmd/flux/testdata/trace/helmrelease-missing-git-ref.txt
deleted file mode 100644
index 7eb18c5012f1481fca2c665caf01a6d818a0d4c0..0000000000000000000000000000000000000000
--- a/cmd/flux/testdata/trace/helmrelease-missing-git-ref.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-
-Object:        HelmRelease/podinfo
-Namespace:     podinfo
-Status:        Managed by Flux
----
-Kustomization: infrastructure
-Namespace:     flux-system
-Path:          ./infrastructure
-Revision:      main/696f056df216eea4f9401adbee0ff744d4df390f
-Status:        Last reconciled at 2021-08-01 04:52:56 +0000 UTC
-Message:       Applied revision: main/696f056df216eea4f9401adbee0ff744d4df390f
----
-GitRepository: flux-system
-Namespace:     flux-system
-URL:           ssh://git@github.com/example/repo
-Revision:      main/696f056df216eea4f9401adbee0ff744d4df390f
-Status:        Last reconciled at 2021-07-20 00:48:16 +0000 UTC
-Message:       Fetched revision: main/696f056df216eea4f9401adbee0ff744d4df390f
diff --git a/cmd/flux/testdata/trace/helmrelease-missing-git-ref.yaml b/cmd/flux/testdata/trace/helmrelease-missing-git-ref.yaml
deleted file mode 100644
index dee892aee291aeec6dc289b81acb3f6e69a1aad9..0000000000000000000000000000000000000000
--- a/cmd/flux/testdata/trace/helmrelease-missing-git-ref.yaml
+++ /dev/null
@@ -1,73 +0,0 @@
----
-apiVersion: helm.toolkit.fluxcd.io/v2beta1
-kind: HelmRelease
-metadata:
-  labels:
-    kustomize.toolkit.fluxcd.io/name: infrastructure
-    kustomize.toolkit.fluxcd.io/namespace: flux-system
-  name: podinfo
-  namespace: podinfo
-spec:
-  chart:
-    spec:
-      chart: podinfo
-      sourceRef:
-        kind: HelmRepository
-        name: podinfo
-        namespace: flux-system
-status:
-  conditions:
-  - lastTransitionTime: "2021-07-16T15:42:20Z"
-    message: Release reconciliation succeeded
-    reason: ReconciliationSucceeded
-    status: "True"
-    type: Ready
-  helmChart: flux-system/podinfo-podinfo
-  lastAppliedRevision: 6.0.0
-  lastAttemptedRevision: 6.0.0
-  lastAttemptedValuesChecksum: c31db75d05b7515eba2eef47bd71038c74b2e531
----
-apiVersion: kustomize.toolkit.fluxcd.io/v1beta1
-kind: Kustomization
-metadata:
-  name: infrastructure
-  namespace: flux-system
-spec:
-  path: ./infrastructure
-  sourceRef:
-    kind: GitRepository
-    name: flux-system
-  validation: client
-status:
-  conditions:
-  - lastTransitionTime: "2021-08-01T04:52:56Z"
-    message: 'Applied revision: main/696f056df216eea4f9401adbee0ff744d4df390f'
-    reason: ReconciliationSucceeded
-    status: "True"
-    type: Ready
-  lastAppliedRevision: main/696f056df216eea4f9401adbee0ff744d4df390f
----
-apiVersion: source.toolkit.fluxcd.io/v1beta1
-kind: GitRepository
-metadata:
-  labels:
-    kustomize.toolkit.fluxcd.io/name: flux-system
-    kustomize.toolkit.fluxcd.io/namespace: flux-system
-  name: flux-system
-  namespace: flux-system
-spec:
-  gitImplementation: go-git
-  secretRef:
-    name: flux-system
-  url: ssh://git@github.com/example/repo
-status:
-  artifact:
-    lastUpdateTime: "2021-08-01T04:28:42Z"
-    revision: main/696f056df216eea4f9401adbee0ff744d4df390f
-  conditions:
-  - lastTransitionTime: "2021-07-20T00:48:16Z"
-    message: 'Fetched revision: main/696f056df216eea4f9401adbee0ff744d4df390f'
-    reason: GitOperationSucceed
-    status: "True"
-    type: Ready
-
diff --git a/cmd/flux/testdata/trace/helmrelease.yaml b/cmd/flux/testdata/trace/helmrelease.yaml
index 4f0db83df72d8afe7f9558875a976f7a36c5f58f..90df86f458f08de4a2ce7666d5445803c3fa131c 100644
--- a/cmd/flux/testdata/trace/helmrelease.yaml
+++ b/cmd/flux/testdata/trace/helmrelease.yaml
@@ -1,4 +1,14 @@
 ---
+apiVersion: v1
+kind: Namespace
+metadata:
+  name: flux-system
+---
+apiVersion: v1
+kind: Namespace
+metadata:
+  name: podinfo
+---
 apiVersion: helm.toolkit.fluxcd.io/v2beta1
 kind: HelmRelease
 metadata:
@@ -15,6 +25,7 @@ spec:
         kind: HelmRepository
         name: podinfo
         namespace: flux-system
+  interval: 5m
 status:
   conditions:
   - lastTransitionTime: "2021-07-16T15:42:20Z"
@@ -38,6 +49,8 @@ spec:
     kind: GitRepository
     name: flux-system
   validation: client
+  interval: 5m
+  prune: false
 status:
   conditions:
   - lastTransitionTime: "2021-08-01T04:52:56Z"
@@ -62,14 +75,16 @@ spec:
   secretRef:
     name: flux-system
   url: ssh://git@github.com/example/repo
+  interval: 5m
 status:
   artifact:
     lastUpdateTime: "2021-08-01T04:28:42Z"
     revision: main/696f056df216eea4f9401adbee0ff744d4df390f
+    path: "example"
+    url: "example"
   conditions:
   - lastTransitionTime: "2021-07-20T00:48:16Z"
     message: 'Fetched revision: main/696f056df216eea4f9401adbee0ff744d4df390f'
     reason: GitOperationSucceed
     status: "True"
     type: Ready
-
diff --git a/cmd/flux/trace.go b/cmd/flux/trace.go
index c18449f131a2b638c871073922cbe84227388bb2..807cdaaf75cafe0a2d765f1685225d855a283b66 100644
--- a/cmd/flux/trace.go
+++ b/cmd/flux/trace.go
@@ -89,7 +89,7 @@ func traceCmdRun(cmd *cobra.Command, args []string) error {
 	ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
 	defer cancel()
 
-	kubeClient, err := rootCtx.kubeManager.NewClient(rootArgs.kubeconfig, rootArgs.kubecontext)
+	kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
 	if err != nil {
 		return err
 	}
diff --git a/cmd/flux/trace_test.go b/cmd/flux/trace_test.go
index c0b538e31fe6d7fb9e896708f916c0db512c039b..c30951ef58f22fb48d174ff74a685f96a9785866 100644
--- a/cmd/flux/trace_test.go
+++ b/cmd/flux/trace_test.go
@@ -9,7 +9,7 @@ import (
 func TestTraceNoArgs(t *testing.T) {
 	cmd := cmdTestCase{
 		args:            "trace",
-		testClusterMode: FakeClusterMode,
+		testClusterMode: TestEnvClusterMode,
 		wantError:       true,
 		goldenValue:     "object name is required",
 	}
@@ -19,7 +19,7 @@ func TestTraceNoArgs(t *testing.T) {
 func TestTraceDeployment(t *testing.T) {
 	cmd := cmdTestCase{
 		args:            "trace podinfo -n podinfo --kind deployment --api-version=apps/v1",
-		testClusterMode: FakeClusterMode,
+		testClusterMode: TestEnvClusterMode,
 		wantError:       false,
 		goldenFile:      "testdata/trace/deployment.txt",
 		objectFile:      "testdata/trace/deployment.yaml",
@@ -30,21 +30,10 @@ func TestTraceDeployment(t *testing.T) {
 func TestTraceHelmRelease(t *testing.T) {
 	cmd := cmdTestCase{
 		args:            "trace podinfo -n podinfo --kind HelmRelease --api-version=helm.toolkit.fluxcd.io/v2beta1",
-		testClusterMode: FakeClusterMode,
+		testClusterMode: TestEnvClusterMode,
 		wantError:       false,
 		goldenFile:      "testdata/trace/helmrelease.txt",
 		objectFile:      "testdata/trace/helmrelease.yaml",
 	}
 	cmd.runTestCmd(t)
 }
-
-func TestTraceHelmReleaseMissingGitRef(t *testing.T) {
-	cmd := cmdTestCase{
-		args:            "trace podinfo -n podinfo --kind HelmRelease --api-version=helm.toolkit.fluxcd.io/v2beta1",
-		testClusterMode: FakeClusterMode,
-		wantError:       false,
-		goldenFile:      "testdata/trace/helmrelease-missing-git-ref.txt",
-		objectFile:      "testdata/trace/helmrelease-missing-git-ref.yaml",
-	}
-	cmd.runTestCmd(t)
-}
diff --git a/cmd/flux/version_test.go b/cmd/flux/version_test.go
index 94419bc023965c24db78368a92cc38c97d095b5f..7dde5b0cd8ecacc11908386f88d4cdeb8df59f79 100644
--- a/cmd/flux/version_test.go
+++ b/cmd/flux/version_test.go
@@ -8,8 +8,9 @@ import (
 
 func TestVersion(t *testing.T) {
 	cmd := cmdTestCase{
-		args:        "--version",
-		goldenValue: "flux version 0.0.0-dev.0\n",
+		args:            "--version",
+		testClusterMode: TestEnvClusterMode,
+		goldenValue:     "flux version 0.0.0-dev.0\n",
 	}
 	cmd.runTestCmd(t)
 }
diff --git a/internal/utils/utils.go b/internal/utils/utils.go
index db323b4c90a48001d883e144be90522b73fce110..d06629e24c857d9a3bb9c3d0b82cdbd35af557da 100644
--- a/internal/utils/utils.go
+++ b/internal/utils/utils.go
@@ -131,36 +131,6 @@ func KubeConfig(kubeConfigPath string, kubeContext string) (*rest.Config, error)
 	return cfg, nil
 }
 
-// KubeManger creates a Kubernetes client.Client. This interface exists to
-// facilitate unit testing and provide a fake client.
-type KubeManager interface {
-	NewClient(string, string) (client.WithWatch, error)
-}
-
-type defaultKubeManager struct{}
-
-func DefaultKubeManager() KubeManager {
-	var manager defaultKubeManager
-	return manager
-}
-
-func (m defaultKubeManager) NewClient(kubeConfigPath string, kubeContext string) (client.WithWatch, error) {
-	cfg, err := KubeConfig(kubeConfigPath, kubeContext)
-	if err != nil {
-		return nil, fmt.Errorf("kubernetes client initialization failed: %w", err)
-	}
-
-	scheme := NewScheme()
-	kubeClient, err := client.NewWithWatch(cfg, client.Options{
-		Scheme: scheme,
-	})
-	if err != nil {
-		return nil, fmt.Errorf("kubernetes client initialization failed: %w", err)
-	}
-
-	return kubeClient, nil
-}
-
 // Create the Scheme, methods for serializing and deserializing API objects
 // which can be shared by tests.
 func NewScheme() *apiruntime.Scheme {
@@ -180,9 +150,20 @@ func NewScheme() *apiruntime.Scheme {
 }
 
 func KubeClient(kubeConfigPath string, kubeContext string) (client.WithWatch, error) {
-	m := DefaultKubeManager()
-	kubeClient, err := m.NewClient(kubeConfigPath, kubeContext)
-	return kubeClient, err
+	cfg, err := KubeConfig(kubeConfigPath, kubeContext)
+	if err != nil {
+		return nil, fmt.Errorf("kubernetes client initialization failed: %w", err)
+	}
+
+	scheme := NewScheme()
+	kubeClient, err := client.NewWithWatch(cfg, client.Options{
+		Scheme: scheme,
+	})
+	if err != nil {
+		return nil, fmt.Errorf("kubernetes client initialization failed: %w", err)
+	}
+
+	return kubeClient, nil
 }
 
 // SplitKubeConfigPath splits the given KUBECONFIG path based on the runtime OS