diff options
author | Shawn O. Pearce <spearce@spearce.org> | 2006-12-30 23:32:38 -0500 |
---|---|---|
committer | Junio C Hamano <junkio@cox.net> | 2007-01-10 15:03:09 -0800 |
commit | 7eff28a9b42cb0d3aad932338b2e645fc6ed8fa9 (patch) | |
tree | c22c8cf02e3b09568198fa405ba7322aafe328ae | |
parent | 4b441f47cefe7f4861167a151a395606e1a16745 (diff) | |
download | git-7eff28a9b42cb0d3aad932338b2e645fc6ed8fa9.tar.gz |
Disallow working directory commands in a bare repository.
If the user tries to run a porcelainish command which requires
a working directory in a bare repository they may get unexpected
results which are difficult to predict and may differ from command
to command.
Instead we should detect that the current repository is a bare
repository and refuse to run the command there, as there is no
working directory associated with it.
[jc: updated Shawn's original somewhat -- bugs are mine.]
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
-rwxr-xr-x | git-am.sh | 1 | ||||
-rwxr-xr-x | git-checkout.sh | 1 | ||||
-rwxr-xr-x | git-clean.sh | 1 | ||||
-rwxr-xr-x | git-commit.sh | 1 | ||||
-rwxr-xr-x | git-merge.sh | 1 | ||||
-rwxr-xr-x | git-pull.sh | 1 | ||||
-rwxr-xr-x | git-rebase.sh | 1 | ||||
-rwxr-xr-x | git-reset.sh | 1 | ||||
-rwxr-xr-x | git-revert.sh | 1 | ||||
-rwxr-xr-x | git-sh-setup.sh | 5 | ||||
-rw-r--r-- | git.c | 15 |
11 files changed, 25 insertions, 4 deletions
@@ -7,6 +7,7 @@ USAGE='[--signoff] [--dotest=<dir>] [--utf8] [--binary] [--3way] or, when resuming [--skip | --resolved]' . git-sh-setup set_reflog_action am +require_work_tree git var GIT_COMMITTER_IDENT >/dev/null || exit diff --git a/git-checkout.sh b/git-checkout.sh index 92ec069a3a..a5649a0504 100755 --- a/git-checkout.sh +++ b/git-checkout.sh @@ -3,6 +3,7 @@ USAGE='[-f] [-b <new_branch>] [-m] [<branch>] [<paths>...]' SUBDIRECTORY_OK=Sometimes . git-sh-setup +require_work_tree old_name=HEAD old=$(git-rev-parse --verify $old_name 2>/dev/null) diff --git a/git-clean.sh b/git-clean.sh index 071b974f49..db177a7886 100755 --- a/git-clean.sh +++ b/git-clean.sh @@ -14,6 +14,7 @@ When optional <paths>... arguments are given, the paths affected are further limited to those that match them.' SUBDIRECTORY_OK=Yes . git-sh-setup +require_work_tree ignored= ignoredonly= diff --git a/git-commit.sh b/git-commit.sh index 04aad5e5da..557b90355c 100755 --- a/git-commit.sh +++ b/git-commit.sh @@ -6,6 +6,7 @@ USAGE='[-a] [-s] [-v] [--no-verify] [-m <message> | -F <logfile> | (-C|-c) <commit>] [-u] [--amend] [-e] [--author <author>] [[-i | -o] <path>...]' SUBDIRECTORY_OK=Yes . git-sh-setup +require_work_tree git-rev-parse --verify HEAD >/dev/null 2>&1 || initial_commit=t diff --git a/git-merge.sh b/git-merge.sh index 477002910e..3eef048efc 100755 --- a/git-merge.sh +++ b/git-merge.sh @@ -7,6 +7,7 @@ USAGE='[-n] [--no-commit] [--squash] [-s <strategy>] [-m=<merge-message>] <commi . git-sh-setup set_reflog_action "merge $*" +require_work_tree test -z "$(git ls-files -u)" || die "You are in a middle of conflicted merge." diff --git a/git-pull.sh b/git-pull.sh index c184fb81a4..e9826fc4ce 100755 --- a/git-pull.sh +++ b/git-pull.sh @@ -8,6 +8,7 @@ USAGE='[-n | --no-summary] [--no-commit] [-s strategy]... [<fetch-options>] <rep LONG_USAGE='Fetch one or more remote refs and merge it/them into the current HEAD.' . git-sh-setup set_reflog_action "pull $*" +require_work_tree test -z "$(git ls-files -u)" || die "You are in a middle of conflicted merge." diff --git a/git-rebase.sh b/git-rebase.sh index 828c59ce61..98f9558145 100755 --- a/git-rebase.sh +++ b/git-rebase.sh @@ -29,6 +29,7 @@ Example: git-rebase master~1 topic ' . git-sh-setup set_reflog_action rebase +require_work_tree RESOLVEMSG=" When you have resolved this problem run \"git rebase --continue\". diff --git a/git-reset.sh b/git-reset.sh index 76c8a818d4..b9045bc762 100755 --- a/git-reset.sh +++ b/git-reset.sh @@ -6,6 +6,7 @@ USAGE='[--mixed | --soft | --hard] [<commit-ish>] [ [--] <paths>...]' SUBDIRECTORY_OK=Yes . git-sh-setup set_reflog_action "reset $*" +require_work_tree update= reset_type=--mixed unset rev diff --git a/git-revert.sh b/git-revert.sh index 50cc47b063..f9843c7c8e 100755 --- a/git-revert.sh +++ b/git-revert.sh @@ -19,6 +19,7 @@ case "$0" in die "What are you talking about?" ;; esac . git-sh-setup +require_work_tree no_commit= while case "$#" in 0) break ;; esac diff --git a/git-sh-setup.sh b/git-sh-setup.sh index 7fdc912167..4a02b3825e 100755 --- a/git-sh-setup.sh +++ b/git-sh-setup.sh @@ -36,6 +36,11 @@ is_bare_repository () { esac } +require_work_tree () { + test $(is_bare_repository) = false || + die "fatal: $0 cannot be used without a working tree." +} + if [ -z "$LONG_USAGE" ] then LONG_USAGE="Usage: $0 $USAGE" @@ -199,6 +199,11 @@ const char git_version_string[] = GIT_VERSION; #define RUN_SETUP (1<<0) #define USE_PAGER (1<<1) +/* + * require working tree to be present -- anything uses this needs + * RUN_SETUP for reading from the configuration file. + */ +#define NOT_BARE (1<<2) static void handle_internal_command(int argc, const char **argv, char **envp) { @@ -208,7 +213,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp) int (*fn)(int, const char **, const char *); int option; } commands[] = { - { "add", cmd_add, RUN_SETUP }, + { "add", cmd_add, RUN_SETUP | NOT_BARE }, { "annotate", cmd_annotate, }, { "apply", cmd_apply }, { "archive", cmd_archive }, @@ -239,7 +244,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp) { "mailinfo", cmd_mailinfo }, { "mailsplit", cmd_mailsplit }, { "merge-file", cmd_merge_file }, - { "mv", cmd_mv, RUN_SETUP }, + { "mv", cmd_mv, RUN_SETUP | NOT_BARE }, { "name-rev", cmd_name_rev, RUN_SETUP }, { "pack-objects", cmd_pack_objects, RUN_SETUP }, { "pickaxe", cmd_blame, RUN_SETUP | USE_PAGER }, @@ -252,8 +257,8 @@ static void handle_internal_command(int argc, const char **argv, char **envp) { "rerere", cmd_rerere, RUN_SETUP }, { "rev-list", cmd_rev_list, RUN_SETUP }, { "rev-parse", cmd_rev_parse, RUN_SETUP }, - { "rm", cmd_rm, RUN_SETUP }, - { "runstatus", cmd_runstatus, RUN_SETUP }, + { "rm", cmd_rm, RUN_SETUP | NOT_BARE }, + { "runstatus", cmd_runstatus, RUN_SETUP | NOT_BARE }, { "shortlog", cmd_shortlog, RUN_SETUP | USE_PAGER }, { "show-branch", cmd_show_branch, RUN_SETUP }, { "show", cmd_show, RUN_SETUP | USE_PAGER }, @@ -290,6 +295,8 @@ 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); trace_argv_printf(argv, argc, "trace: built-in: git"); exit(p->fn(argc, argv, prefix)); |