[PATCH] Commands requiring a work tree must not run in GIT_DIR

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch helps when you accidentally run something like git-clean
in the git directory instead of the work tree.

Signed-off-by: Johannes Schindelin <Johannes.Schindelin@xxxxxx>

---

	On Tue, 23 Jan 2007, Yasushi SHOJI wrote:
	
	> At Fri, 19 Jan 2007 11:03:17 -0800,
	> Junio C Hamano wrote:
	> > 
	> > Johannes Schindelin <Johannes.Schindelin@xxxxxx> writes:
	> > 
	> > > On Fri, 19 Jan 2007, Matthias Kestenholz wrote:
	> > > ...
	> > >> Why not check for /.git/ somewhere inside the current 
	> > >> working directory (pwd) ? That's the way mercurial does it 
	> > >> currently, and I think that is a sane thing to do _if_ you 
	> > >> want to protect the user from his own stupidity.
	> > >
	> > > There are valid reasons why you might want to have a 
	> > > (possibly temporary) repository _inside_ the GIT_DIR. You'd 
	> > > break these cases.
	> > 
	> > You are right that strstr(here, "/.git/") is not a good check.
	> > 
	> > If we really care about this problem (and I am not yet 
	> > starting to think we might, but who knows, I reserve the right 
	> > to change my mind every once in a while), we could make the 
	> > commands that deal with working trees (that is, among the 
	> > things under discussion in this thread, 'git-clean' always is, 
	> > and 'git-ls-files' only when it is given options like '-o', 
	> > '-k', '-m', '-i') when the cwd is GIT_DIR or a subdirectory of 
	> > it.
	> 
	> I believe it should be done.

	I only did that for the mentioned commands; your homework: find 
	all other commands (or options) which need that.

 builtin-ls-files.c  |   10 +++++++++-
 builtin-rev-parse.c |    5 +++++
 git-sh-setup.sh     |    3 ++-
 git.c               |    5 +++--
 4 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/builtin-ls-files.c b/builtin-ls-files.c
index 21c2a6e..ac89eb2 100644
--- a/builtin-ls-files.c
+++ b/builtin-ls-files.c
@@ -323,7 +323,7 @@ static const char ls_files_usage[] =
 int cmd_ls_files(int argc, const char **argv, const char *prefix)
 {
 	int i;
-	int exc_given = 0;
+	int exc_given = 0, require_work_tree = 0;
 	struct dir_struct dir;
 
 	memset(&dir, 0, sizeof(dir));
@@ -363,14 +363,17 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
 		}
 		if (!strcmp(arg, "-m") || !strcmp(arg, "--modified")) {
 			show_modified = 1;
+			require_work_tree = 1;
 			continue;
 		}
 		if (!strcmp(arg, "-o") || !strcmp(arg, "--others")) {
 			show_others = 1;
+			require_work_tree = 1;
 			continue;
 		}
 		if (!strcmp(arg, "-i") || !strcmp(arg, "--ignored")) {
 			dir.show_ignored = 1;
+			require_work_tree = 1;
 			continue;
 		}
 		if (!strcmp(arg, "-s") || !strcmp(arg, "--stage")) {
@@ -379,6 +382,7 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
 		}
 		if (!strcmp(arg, "-k") || !strcmp(arg, "--killed")) {
 			show_killed = 1;
+			require_work_tree = 1;
 			continue;
 		}
 		if (!strcmp(arg, "--directory")) {
@@ -447,6 +451,10 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
 		break;
 	}
 
+	if (require_work_tree &&
+			(is_bare_repository() || is_inside_git_dir()))
+		die("This operation must be run in a work tree");
+
 	pathspec = get_pathspec(prefix, argv + i);
 
 	/* Verify that the pathspec matches the prefix */
diff --git a/builtin-rev-parse.c b/builtin-rev-parse.c
index 3b716fb..d53deaa 100644
--- a/builtin-rev-parse.c
+++ b/builtin-rev-parse.c
@@ -347,6 +347,11 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
 				printf("%s/.git\n", cwd);
 				continue;
 			}
+			if (!strcmp(arg, "--is-inside-git-dir")) {
+				printf("%s\n", is_inside_git_dir() ? "true"
+						: "false");
+				continue;
+			}
 			if (!strncmp(arg, "--since=", 8)) {
 				show_datestring("--max-age=", arg+8);
 				continue;
diff --git a/git-sh-setup.sh b/git-sh-setup.sh
index 6b1c142..9114c49 100755
--- a/git-sh-setup.sh
+++ b/git-sh-setup.sh
@@ -48,7 +48,8 @@ cd_to_toplevel () {
 }
 
 require_work_tree () {
-	test $(is_bare_repository) = false ||
+	test $(is_bare_repository) = false &&
+	test $(git-rev-parse --is-inside-git-dir) = false ||
 	die "fatal: $0 cannot be used without a working tree."
 }
 
diff --git a/git.c b/git.c
index 5133a07..2027d1c 100644
--- a/git.c
+++ b/git.c
@@ -302,8 +302,9 @@ static void handle_internal_command(int argc, const char **argv, char **envp)
 			prefix = setup_git_directory();
 		if (p->option & USE_PAGER)
 			setup_pager();
-		if ((p->option & NOT_BARE) && is_bare_repository())
-			die("%s cannot be used in a bare git directory", cmd);
+		if ((p->option & NOT_BARE) &&
+				(is_bare_repository() || is_inside_git_dir()))
+			die("%s must be run in a work tree", cmd);
 		trace_argv_printf(argv, argc, "trace: built-in: git");
 
 		exit(p->fn(argc, argv, prefix));
-
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]