Merge "jiri: Clarify the arg to -remote-branch."
diff --git a/doc.go b/doc.go
index 588efd9..0e3a622 100644
--- a/doc.go
+++ b/doc.go
@@ -406,10 +406,6 @@
 particular, it can be used to create new snapshots and to list existing
 snapshots.
 
-The command-line flag "-remote" determines whether the command pertains to
-"local" snapshots that are only stored locally or "remote" snapshots the are
-revisioned in the manifest repository.
-
 Usage:
    jiri snapshot [flags] <command>
 
@@ -418,6 +414,8 @@
    list        List existing project snapshots
 
 The jiri snapshot flags are:
+ -dir=
+   Directory where snapshot are stored.  Defaults to $JIRI_ROOT/.snapshot.
  -remote=false
    Manage remote snapshots.
 
@@ -431,10 +429,8 @@
 Jiri snapshot create - Create a new project snapshot
 
 The "jiri snapshot create <label>" command captures the current project state in
-a manifest and, depending on the value of the -remote flag, the command either
-stores the manifest in the local $JIRI_ROOT/.snapshots directory, or in the
-manifest repository, pushing the change to the remote repository and thus making
-it available globally.
+a manifest.  If the -push-remote flag is provided, the snapshot is committed and
+pushed upstream.
 
 Internally, snapshots are organized as follows:
 
@@ -463,11 +459,15 @@
 <label> is the snapshot label.
 
 The jiri snapshot create flags are:
+ -push-remote=false
+   Commit and push snapshot upstream.
  -time-format=2006-01-02T15:04:05Z07:00
    Time format for snapshot file name.
 
  -color=true
    Use color to format output.
+ -dir=
+   Directory where snapshot are stored.  Defaults to $JIRI_ROOT/.snapshot.
  -n=false
    Show what commands will run but do not execute them.
  -remote=false
@@ -489,6 +489,8 @@
 The jiri snapshot list flags are:
  -color=true
    Use color to format output.
+ -dir=
+   Directory where snapshot are stored.  Defaults to $JIRI_ROOT/.snapshot.
  -n=false
    Show what commands will run but do not execute them.
  -remote=false
diff --git a/gitutil/.api b/gitutil/.api
index 8bf6ac4..4ba995e 100644
--- a/gitutil/.api
+++ b/gitutil/.api
@@ -7,6 +7,7 @@
 pkg gitutil, method (*Git) BranchesDiffer(string, string) (bool, error)
 pkg gitutil, method (*Git) CheckoutBranch(string, ...CheckoutOpt) error
 pkg gitutil, method (*Git) Clone(string, string) error
+pkg gitutil, method (*Git) CloneRecursive(string, string) error
 pkg gitutil, method (*Git) Commit() error
 pkg gitutil, method (*Git) CommitAmend() error
 pkg gitutil, method (*Git) CommitAmendWithMessage(string) error
diff --git a/gitutil/git.go b/gitutil/git.go
index 879cabd..82d0c3c 100644
--- a/gitutil/git.go
+++ b/gitutil/git.go
@@ -113,6 +113,11 @@
 
 // Clone clones the given repository to the given local path.
 func (g *Git) Clone(repo, path string) error {
+	return g.run("clone", repo, path)
+}
+
+// CloneRecursive clones the given repository recursively to the given local path.
+func (g *Git) CloneRecursive(repo, path string) error {
 	return g.run("clone", "--recursive", repo, path)
 }
 
diff --git a/jiri/.api b/jiri/.api
index 0addbef..384b799 100644
--- a/jiri/.api
+++ b/jiri/.api
@@ -11,10 +11,6 @@
 pkg jiri, method (*X) BinDir() string
 pkg jiri, method (*X) Clone(tool.ContextOpts) *X
 pkg jiri, method (*X) JiriManifestFile() string
-pkg jiri, method (*X) LocalSnapshotDir() string
-pkg jiri, method (*X) ManifestDir() string
-pkg jiri, method (*X) ManifestFile(string) string
-pkg jiri, method (*X) RemoteSnapshotDir() string
 pkg jiri, method (*X) ResolveManifestPath(string) (string, error)
 pkg jiri, method (*X) RootMetaDir() string
 pkg jiri, method (*X) UpdateHistoryDir() string
diff --git a/jiri/x.go b/jiri/x.go
index 685283c..20133dd 100644
--- a/jiri/x.go
+++ b/jiri/x.go
@@ -136,26 +136,6 @@
 	return filepath.Join(x.RootMetaDir(), "update_history")
 }
 
-// LocalSnapshotDir returns the path to the local snapshot directory.
-func (x *X) LocalSnapshotDir() string {
-	return filepath.Join(x.Root, ".snapshot")
-}
-
-// RemoteSnapshotDir returns the path to the remote snapshot directory.
-func (x *X) RemoteSnapshotDir() string {
-	return filepath.Join(x.ManifestDir(), "snapshot")
-}
-
-// ManifestDir returns the path to the manifest directory.
-func (x *X) ManifestDir() string {
-	return filepath.Join(x.Root, ".manifest", "v2")
-}
-
-// ManifestFile returns the path to the manifest file with the given name.
-func (x *X) ManifestFile(name string) string {
-	return filepath.Join(x.ManifestDir(), name)
-}
-
 // ResolveManifestPath resolves the given manifest name to an absolute path in
 // the local filesystem.
 func (x *X) ResolveManifestPath(name string) (string, error) {
@@ -172,18 +152,19 @@
 //
 // TODO(toddw): Remove this logic when the transition to .jiri_manifest is done.
 func (x *X) resolveManifestPathDeprecated(name string) (string, error) {
+	manifestDir := filepath.Join(x.Root, ".manifest", "v2")
 	if name != "" {
 		if filepath.IsAbs(name) {
 			return name, nil
 		}
-		return x.ManifestFile(name), nil
+		return filepath.Join(manifestDir, name), nil
 	}
 	path := filepath.Join(x.Root, ".local_manifest")
 	switch _, err := os.Stat(path); {
 	case err == nil:
 		return path, nil
 	case os.IsNotExist(err):
-		return x.ManifestFile("default"), nil
+		return filepath.Join(manifestDir, "default"), nil
 	default:
 		return "", fmt.Errorf("Stat(%v) failed: %v", path, err)
 	}
diff --git a/jiritest/fake.go b/jiritest/fake.go
index 4987b15..c3e8195 100644
--- a/jiritest/fake.go
+++ b/jiritest/fake.go
@@ -63,7 +63,7 @@
 	if err := fake.WriteRemoteManifest(&project.Manifest{}); err != nil {
 		t.Fatal(err)
 	}
-	if err := jirix.Git().Clone(fake.Projects[manifestProject], filepath.Join(jirix.Root, manifestProject)); err != nil {
+	if err := jirix.Git().CloneRecursive(fake.Projects[manifestProject], filepath.Join(jirix.Root, manifestProject)); err != nil {
 		t.Fatal(err)
 	}
 
diff --git a/profiles/profilescmdline/reader_cmdline.go b/profiles/profilescmdline/reader_cmdline.go
index 1573684..2afac17 100644
--- a/profiles/profilescmdline/reader_cmdline.go
+++ b/profiles/profilescmdline/reader_cmdline.go
@@ -28,7 +28,6 @@
 
 // IsFlagSet returns true if the specified flag has been set on
 // the command line.
-// TODO(cnicolaou): use this to simplify the implementation of profiles.Target
 func IsFlagSet(fs *flag.FlagSet, name string) bool {
 	found := false
 	fs.Visit(func(f *flag.Flag) {
@@ -36,7 +35,7 @@
 			found = true
 		}
 	})
-	return true
+	return found
 }
 
 // NOTE: we use functions to initialize the commands so that we
diff --git a/project/project.go b/project/project.go
index 276aeba..a877633 100644
--- a/project/project.go
+++ b/project/project.go
@@ -1851,7 +1851,12 @@
 		if found && strings.HasPrefix(op.project.Remote, host.Location) {
 			gitHookDir := filepath.Join(tmpDir, ".git", "hooks")
 			for _, githook := range host.GitHooks {
-				mdir := jirix.ManifestDir()
+				// TODO(nlacasse): GitHook paths are relative to the manifest
+				// file.  Currently all manifests live in
+				// JIRI_ROOT/.manifest/v2, but that is changing.  I think
+				// GitHooks should be associated with projects, and their paths
+				// should be relative to the project root.
+				mdir := filepath.Join(jirix.Root, ".manifest", "v2")
 				src, err := s.ReadFile(filepath.Join(mdir, githook.Path))
 				if err != nil {
 					return err
diff --git a/snapshot.go b/snapshot.go
index 1ed9255..3238615 100644
--- a/snapshot.go
+++ b/snapshot.go
@@ -21,14 +21,28 @@
 	"v.io/x/lib/cmdline"
 )
 
+const (
+	defaultSnapshotDir = ".snapshot"
+)
+
 var (
-	remoteFlag     bool
-	timeFormatFlag string
+	snapshotDirFlag string
+	pushRemoteFlag  bool
+	timeFormatFlag  string
+
+	// TODO(nlacasse): Remove the -remote flag once all users have moved to the
+	// -push-remote flag.
+	remoteFlag bool
 )
 
 func init() {
-	cmdSnapshot.Flags.BoolVar(&remoteFlag, "remote", false, "Manage remote snapshots.")
+	cmdSnapshot.Flags.StringVar(&snapshotDirFlag, "dir", "", "Directory where snapshot are stored.  Defaults to $JIRI_ROOT/.snapshot.")
+	cmdSnapshotCreate.Flags.BoolVar(&pushRemoteFlag, "push-remote", false, "Commit and push snapshot upstream.")
 	cmdSnapshotCreate.Flags.StringVar(&timeFormatFlag, "time-format", time.RFC3339, "Time format for snapshot file name.")
+
+	// TODO(nlacasse): Remove the -remote flag once all users have moved to the
+	// -push-remote flag.
+	cmdSnapshot.Flags.BoolVar(&remoteFlag, "remote", false, "Manage remote snapshots.")
 }
 
 var cmdSnapshot = &cmdline.Command{
@@ -38,10 +52,6 @@
 The "jiri snapshot" command can be used to manage project snapshots.
 In particular, it can be used to create new snapshots and to list
 existing snapshots.
-
-The command-line flag "-remote" determines whether the command
-pertains to "local" snapshots that are only stored locally or "remote"
-snapshots the are revisioned in the manifest repository.
 `,
 	Children: []*cmdline.Command{cmdSnapshotCreate, cmdSnapshotList},
 }
@@ -52,12 +62,9 @@
 	Name:   "create",
 	Short:  "Create a new project snapshot",
 	Long: `
-The "jiri snapshot create <label>" command captures the current project
-state in a manifest and, depending on the value of the -remote flag,
-the command either stores the manifest in the local
-$JIRI_ROOT/.snapshots directory, or in the manifest repository, pushing
-the change to the remote repository and thus making it available
-globally.
+The "jiri snapshot create <label>" command captures the current project state
+in a manifest.  If the -push-remote flag is provided, the snapshot is committed
+and pushed upstream.
 
 Internally, snapshots are organized as follows:
 
@@ -94,75 +101,59 @@
 		return err
 	}
 	snapshotFile := filepath.Join(snapshotDir, "labels", label, time.Now().Format(timeFormatFlag))
-	// Either atomically create a new snapshot that captures the project
-	// state and push the changes to the remote repository (if
-	// applicable), or fail with no effect.
+
+	if !remoteFlag && !pushRemoteFlag {
+		// No git operations necessary.  Just create the snapshot file.
+		return createSnapshot(jirix, snapshotDir, snapshotFile, label)
+	}
+
+	// Attempt to create a snapshot on a clean master branch.  If snapshot
+	// creation fails, return to the state we were in before.
 	createFn := func() error {
 		revision, err := jirix.Git().CurrentRevision()
 		if err != nil {
 			return err
 		}
 		if err := createSnapshot(jirix, snapshotDir, snapshotFile, label); err != nil {
-			// Clean up on all errors.
 			jirix.Git().Reset(revision)
 			jirix.Git().RemoveUntrackedFiles()
 			return err
 		}
-		return nil
+		return commitAndPushChanges(jirix, snapshotDir, snapshotFile, label)
 	}
 
-	// Execute the above function in the snapshot directory.
+	// Execute the above function in the snapshot directory on a clean master branch.
 	p := project.Project{
 		Path:     snapshotDir,
 		Protocol: "git",
 		Revision: "HEAD",
 	}
-	if err := project.ApplyToLocalMaster(jirix, project.Projects{p.Key(): p}, createFn); err != nil {
-		return err
-	}
-	return nil
+	return project.ApplyToLocalMaster(jirix, project.Projects{p.Key(): p}, createFn)
 }
 
-// getSnapshotDir returns the path to the snapshot directory, respecting the
-// value of the "-remote" command-line flag.  It performs validation that the
-// directory exists and is initialized.
+// getSnapshotDir returns the path to the snapshot directory, creating it if
+// necessary.
 func getSnapshotDir(jirix *jiri.X) (string, error) {
-	dir := jirix.LocalSnapshotDir()
+	dir := snapshotDirFlag
+	if dir == "" {
+		dir = filepath.Join(jirix.Root, defaultSnapshotDir)
+	}
+
+	// TODO(nlacasse): Remove once there are no more user of the -remote flag.
 	if remoteFlag {
-		dir = jirix.RemoteSnapshotDir()
+		dir = filepath.Join(jirix.Root, ".manifest", "v2", "snapshot")
 	}
-	s := jirix.NewSeq()
-	switch _, err := s.Stat(dir); {
-	case err == nil:
-		return dir, nil
-	case !runutil.IsNotExist(err):
-		return "", err
-	case remoteFlag:
-		if err := s.MkdirAll(dir, 0755).Done(); err != nil {
-			return "", err
-		}
-		return dir, nil
-	}
-	// Create a new local snapshot directory.
-	createFn := func() (e error) {
-		if err := s.MkdirAll(dir, 0755).Done(); err != nil {
-			return err
-		}
-		if err := jirix.Git().Init(dir); err != nil {
-			return err
-		}
+
+	if !filepath.IsAbs(dir) {
 		cwd, err := os.Getwd()
 		if err != nil {
-			return err
+			return "", err
 		}
-		defer collect.Error(func() error { return jirix.NewSeq().Chdir(cwd).Done() }, &e)
-		if err := s.Chdir(dir).Done(); err != nil {
-			return err
-		}
-		return jirix.Git().Commit()
+		dir = filepath.Join(cwd, dir)
 	}
-	if err := createFn(); err != nil {
-		s.RemoveAll(dir)
+
+	// Make sure directory exists.
+	if err := jirix.NewSeq().MkdirAll(dir, 0755).Done(); err != nil {
 		return "", err
 	}
 	return dir, nil
@@ -181,23 +172,15 @@
 	symlink := filepath.Join(snapshotDir, label)
 	newSymlink := symlink + ".new"
 	relativeSnapshotPath := strings.TrimPrefix(snapshotFile, snapshotDir+string(os.PathSeparator))
-	if err := s.RemoveAll(newSymlink).
+	return s.RemoveAll(newSymlink).
 		Symlink(relativeSnapshotPath, newSymlink).
-		Rename(newSymlink, symlink).Done(); err != nil {
-		return err
-	}
-
-	// Revision the changes.
-	if err := revisionChanges(jirix, snapshotDir, snapshotFile, label); err != nil {
-		return err
-	}
-	return nil
+		Rename(newSymlink, symlink).Done()
 }
 
-// revisionChanges commits changes identified by the given manifest
-// file and label to the manifest repository and (if applicable)
-// pushes these changes to the remote repository.
-func revisionChanges(jirix *jiri.X, snapshotDir, snapshotFile, label string) (e error) {
+// commitAndPushChanges commits changes identified by the given manifest file
+// and label to the containing repository and pushes these changes to the
+// remote repository.
+func commitAndPushChanges(jirix *jiri.X, snapshotDir, snapshotFile, label string) (e error) {
 	cwd, err := os.Getwd()
 	if err != nil {
 		return err
@@ -217,10 +200,8 @@
 	if err := jirix.Git().CommitWithMessage(fmt.Sprintf("adding snapshot %q for label %q", name, label)); err != nil {
 		return err
 	}
-	if remoteFlag {
-		if err := jirix.Git().Push("origin", "master", gitutil.VerifyOpt(false)); err != nil {
-			return err
-		}
+	if err := jirix.Git().Push("origin", "master", gitutil.VerifyOpt(false)); err != nil {
+		return err
 	}
 	return nil
 }
diff --git a/snapshot_test.go b/snapshot_test.go
index 8bbcf1a..7fb99d1 100644
--- a/snapshot_test.go
+++ b/snapshot_test.go
@@ -11,6 +11,7 @@
 	"path/filepath"
 	"testing"
 
+	"v.io/jiri/gitutil"
 	"v.io/jiri/jiri"
 	"v.io/jiri/jiritest"
 	"v.io/jiri/project"
@@ -18,6 +19,9 @@
 )
 
 func createLabelDir(t *testing.T, jirix *jiri.X, snapshotDir, name string, snapshots []string) {
+	if snapshotDir == "" {
+		snapshotDir = filepath.Join(jirix.Root, defaultSnapshotDir)
+	}
 	s := jirix.NewSeq()
 	labelDir, perm := filepath.Join(snapshotDir, "labels", name), os.FileMode(0700)
 	if err := s.MkdirAll(labelDir, perm).Done(); err != nil {
@@ -60,21 +64,20 @@
 }
 
 func TestList(t *testing.T) {
+	resetFlags()
 	fake, cleanup := jiritest.NewFakeJiriRoot(t)
 	defer cleanup()
 
-	remoteSnapshotDir := fake.X.RemoteSnapshotDir()
-	localSnapshotDir := fake.X.LocalSnapshotDir()
+	snapshotDir1 := "" // Should use default dir.
+	snapshotDir2 := filepath.Join(fake.X.Root, "some/other/dir")
 
 	// Create a test suite.
 	tests := []config{
 		config{
-			remote: false,
-			dir:    localSnapshotDir,
+			dir: snapshotDir1,
 		},
 		config{
-			remote: true,
-			dir:    remoteSnapshotDir,
+			dir: snapshotDir2,
 		},
 	}
 	labels := []label{
@@ -89,7 +92,7 @@
 	}
 
 	for _, test := range tests {
-		remoteFlag = test.remote
+		snapshotDirFlag = test.dir
 		// Create the snapshots directory and populate it with the
 		// data specified by the test suite.
 		for _, label := range labels {
@@ -174,7 +177,187 @@
 	}
 }
 
+func resetFlags() {
+	snapshotDirFlag = ""
+	pushRemoteFlag = false
+	remoteFlag = false
+}
+
+func TestGetSnapshotDir(t *testing.T) {
+	resetFlags()
+	defer resetFlags()
+	fake, cleanup := jiritest.NewFakeJiriRoot(t)
+	defer cleanup()
+
+	// With all flags at default values, snapshot dir should be default.
+	resetFlags()
+	got, err := getSnapshotDir(fake.X)
+	if err != nil {
+		t.Fatalf("getSnapshotDir() failed: %v\n", err)
+	}
+	if want := filepath.Join(fake.X.Root, defaultSnapshotDir); got != want {
+		t.Errorf("unexpected snapshot dir: got %v want %v", got, want)
+	}
+
+	// With remote flag set, snapshot dir should be JIRI_ROOT/.manifest/v2/snapshot.
+	resetFlags()
+	remoteFlag = true
+	got, err = getSnapshotDir(fake.X)
+	if err != nil {
+		t.Fatalf("getSnapshotDir() failed: %v\n", err)
+	}
+	if want := filepath.Join(fake.X.Root, ".manifest", "v2", "snapshot"); got != want {
+		t.Errorf("unexpected snapshot dir: got %v want %v", got, want)
+	}
+
+	// With dir flag set to absolute path, snapshot dir should be value of dir
+	// flag.
+	resetFlags()
+	tempDir, err := fake.X.NewSeq().TempDir("", "")
+	if err != nil {
+		t.Fatalf("TempDir() failed: %v", err)
+	}
+	defer fake.X.NewSeq().RemoveAll(tempDir).Done()
+	snapshotDirFlag = tempDir
+	got, err = getSnapshotDir(fake.X)
+	if err != nil {
+		t.Fatalf("getSnapshotDir() failed: %v\n", err)
+	}
+	if want := snapshotDirFlag; got != want {
+		t.Errorf("unexpected snapshot dir: got %v want %v", got, want)
+	}
+
+	// With dir flag set to relative path, snapshot dir should absolute path
+	// rooted at current working dir.
+	resetFlags()
+	snapshotDirFlag = "some/relative/path"
+	cwd, err := os.Getwd()
+	if err != nil {
+		t.Fatalf("os.Getwd() failed: %v", err)
+	}
+	got, err = getSnapshotDir(fake.X)
+	if err != nil {
+		t.Fatalf("getSnapshotDir() failed: %v\n", err)
+	}
+	if want := filepath.Join(cwd, snapshotDirFlag); got != want {
+		t.Errorf("unexpected snapshot dir: got %v want %v", got, want)
+	}
+}
+
+// TestCreate tests creating and checking out a snapshot.
 func TestCreate(t *testing.T) {
+	resetFlags()
+	defer resetFlags()
+	fake, cleanup := jiritest.NewFakeJiriRoot(t)
+	defer cleanup()
+	s := fake.X.NewSeq()
+
+	// Setup the initial remote and local projects.
+	numProjects, remoteProjects := 2, []string{}
+	for i := 0; i < numProjects; i++ {
+		if err := fake.CreateRemoteProject(remoteProjectName(i)); err != nil {
+			t.Fatalf("%v", err)
+		}
+		if err := fake.AddProject(project.Project{
+			Name:   remoteProjectName(i),
+			Path:   localProjectName(i),
+			Remote: fake.Projects[remoteProjectName(i)],
+		}); err != nil {
+			t.Fatalf("%v", err)
+		}
+	}
+
+	// Create initial commits in the remote projects and use UpdateUniverse()
+	// to mirror them locally.
+	for i := 0; i < numProjects; i++ {
+		writeReadme(t, fake.X, fake.Projects[remoteProjectName(i)], "revision 1")
+	}
+	if err := project.UpdateUniverse(fake.X, true); err != nil {
+		t.Fatalf("%v", err)
+	}
+
+	// Create a snapshot.
+	var stdout bytes.Buffer
+	fake.X.Context = tool.NewContext(tool.ContextOpts{Stdout: &stdout})
+	if err := runSnapshotCreate(fake.X, []string{"test-local"}); err != nil {
+		t.Fatalf("%v", err)
+	}
+
+	// Remove the local project repositories.
+	for i, _ := range remoteProjects {
+		localProject := filepath.Join(fake.X.Root, localProjectName(i))
+		if err := s.RemoveAll(localProject).Done(); err != nil {
+			t.Fatalf("%v", err)
+		}
+	}
+
+	// Check that invoking the UpdateUniverse() with the snapshot restores the
+	// local repositories.
+	snapshotDir := filepath.Join(fake.X.Root, defaultSnapshotDir)
+	snapshotFile := filepath.Join(snapshotDir, "test-local")
+	localX := fake.X.Clone(tool.ContextOpts{
+		Manifest: &snapshotFile,
+	})
+	if err := project.UpdateUniverse(localX, true); err != nil {
+		t.Fatalf("%v", err)
+	}
+	for i, _ := range remoteProjects {
+		localProject := filepath.Join(fake.X.Root, localProjectName(i))
+		checkReadme(t, fake.X, localProject, "revision 1")
+	}
+}
+
+// TestCreatePushRemote checks that creating a snapshot with the -push-remote
+// flag causes the snapshot to be committed and pushed upstream.
+func TestCreatePushRemote(t *testing.T) {
+	resetFlags()
+	defer resetFlags()
+
+	fake, cleanup := jiritest.NewFakeJiriRoot(t)
+	defer cleanup()
+
+	fake.EnableRemoteManifestPush()
+	defer fake.DisableRemoteManifestPush()
+
+	manifestDir := filepath.Join(fake.X.Root, ".manifest")
+	snapshotDir := filepath.Join(manifestDir, "snapshot")
+	label := "test"
+
+	git := gitutil.New(fake.X.NewSeq(), manifestDir)
+	commitCount, err := git.CountCommits("master", "")
+	if err != nil {
+		t.Fatalf("git.CountCommits(\"master\", \"\") failed: %v", err)
+	}
+
+	// Create snapshot with -push-remote flag set to true.
+	snapshotDirFlag = snapshotDir
+	pushRemoteFlag = true
+	if err := runSnapshotCreate(fake.X, []string{label}); err != nil {
+		t.Fatalf("%v", err)
+	}
+
+	// Check that repo has one new commit.
+	newCommitCount, err := git.CountCommits("master", "")
+	if err != nil {
+		t.Fatalf("git.CountCommits(\"master\", \"\") failed: %v", err)
+	}
+	if got, want := newCommitCount, commitCount+1; got != want {
+		t.Errorf("unexpected commit count: got %v want %v", got, want)
+	}
+
+	// Check that new label is commited.
+	labelFile := filepath.Join(snapshotDir, "labels", label)
+	if !git.IsFileCommitted(labelFile) {
+		t.Errorf("expected file %v to be committed but it was not", labelFile)
+	}
+}
+
+// TestCreateDeprecated tests "local" and "remote" snapshot creation.
+// TODO(nlacasse): Delete this test once the old -remote flag has been removed.
+// The new snapshot behavior is tested in TestCreate and TestCreatePushRemote.
+func TestCreateDeprecated(t *testing.T) {
+	resetFlags()
+	defer resetFlags()
 	fake, cleanup := jiritest.NewFakeJiriRoot(t)
 	defer cleanup()
 	s := fake.X.NewSeq()
@@ -221,7 +404,7 @@
 
 	// Check that invoking the UpdateUniverse() with the local
 	// snapshot restores the local repositories.
-	snapshotDir := fake.X.LocalSnapshotDir()
+	snapshotDir := filepath.Join(fake.X.Root, defaultSnapshotDir)
 	snapshotFile := filepath.Join(snapshotDir, "test-local")
 	localX := fake.X.Clone(tool.ContextOpts{
 		Manifest: &snapshotFile,