Commands such as `commit` and `tag` that lets you edit
messages by launching an editor uses the value of this
variable when it is set, and the environment variable
- `GIT_EDITOR` is not set. The order of preference is
- `GIT_EDITOR` environment, `core.editor`, `VISUAL` and
- `EDITOR` environment variables and then finally `vi`.
+ `GIT_EDITOR` is not set. See linkgit:git-var[1].
core.pager::
The command that git will use to paginate output. Can
The editor used to edit the commit log message will be chosen from the
GIT_EDITOR environment variable, the core.editor configuration variable, the
VISUAL environment variable, or the EDITOR environment variable (in that
-order).
+order). See linkgit:git-var[1] for details.
HOOKS
-----
The --cc option must be repeated for each user you want on the cc list.
--compose::
- Use $GIT_EDITOR, core.editor, $VISUAL, or $EDITOR to edit an
- introductory message for the patch series.
+ Invoke a text editor (see GIT_EDITOR in linkgit:git-var[1])
+ to edit an introductory message for the patch series.
+
When '--compose' is used, git send-email will use the From, Subject, and
In-Reply-To headers specified in the message. If the body of the message
GIT_COMMITTER_IDENT::
The person who put a piece of code into git.
+GIT_EDITOR::
+ Text editor for use by git commands. The value is meant to be
+ interpreted by the shell when it is used. Examples: `~/bin/vi`,
+ `$SOME_ENVIRONMENT_VARIABLE`, `"C:\Program Files\Vim\gvim.exe"
+ --nofork`. The order of preference is the `$GIT_EDITOR`
+ environment variable, then `core.editor` configuration, then
+ `$VISUAL`, then `$EDITOR`, and then finally 'vi'.
+
+GIT_PAGER::
+ Text viewer for use by git commands (e.g., 'less'). The value
+ is meant to be interpreted by the shell. The order of preference
+ is the `$GIT_PAGER` environment variable, then `core.pager`
+ configuration, then `$PAGER`, and then finally 'less'.
+
Diagnostics
-----------
You don't exist. Go away!::
# memory allocators with the nedmalloc allocator written by Niall Douglas.
#
# Define NO_REGEX if you have no or inferior regex support in your C library.
+#
+# Define DEFAULT_PAGER to a sensible pager command (defaults to "less") if
+# you want to use something different. The value will be interpreted by the
+# shell at runtime when it is used.
+#
+# Define DEFAULT_EDITOR to a sensible editor command (defaults to "vi") if you
+# want to use something different. The value will be interpreted by the shell
+# if necessary when it is used. Examples:
+#
+# DEFAULT_EDITOR='~/bin/vi',
+# DEFAULT_EDITOR='$GIT_FALLBACK_EDITOR',
+# DEFAULT_EDITOR='"C:\Program Files\Vim\gvim.exe" --nofork'
GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE
@$(SHELL_PATH) ./GIT-VERSION-GEN
$(COMPAT_CFLAGS)
LIB_OBJS += $(COMPAT_OBJS)
+# Quote for C
+
+ifdef DEFAULT_EDITOR
+DEFAULT_EDITOR_CQ = "$(subst ",\",$(subst \,\\,$(DEFAULT_EDITOR)))"
+DEFAULT_EDITOR_CQ_SQ = $(subst ','\'',$(DEFAULT_EDITOR_CQ))
+
+BASIC_CFLAGS += -DDEFAULT_EDITOR='$(DEFAULT_EDITOR_CQ_SQ)'
+endif
+
+ifdef DEFAULT_PAGER
+DEFAULT_PAGER_CQ = "$(subst ",\",$(subst \,\\,$(DEFAULT_PAGER)))"
+DEFAULT_PAGER_CQ_SQ = $(subst ','\'',$(DEFAULT_PAGER_CQ))
+
+BASIC_CFLAGS += -DDEFAULT_PAGER='$(DEFAULT_PAGER_CQ_SQ)'
+endif
+
ALL_CFLAGS += $(BASIC_CFLAGS)
ALL_LDFLAGS += $(BASIC_LDFLAGS)
extern const char *git_committer_info(int);
extern const char *fmt_ident(const char *name, const char *email, const char *date_str, int);
extern const char *fmt_name(const char *name, const char *email);
+extern const char *git_editor(void);
+extern const char *git_pager(void);
struct checkout {
const char *base_dir;
tmpFile.write(submitTemplate + separatorLine + diff + newdiff)
tmpFile.close()
mtime = os.stat(fileName).st_mtime
- defaultEditor = "vi"
- if platform.system() == "Windows":
- defaultEditor = "notepad"
if os.environ.has_key("P4EDITOR"):
editor = os.environ.get("P4EDITOR")
else:
- editor = os.environ.get("EDITOR", defaultEditor);
+ editor = read_pipe("git var GIT_EDITOR")
system(editor + " " + fileName)
response = "y"
#include "strbuf.h"
#include "run-command.h"
-int launch_editor(const char *path, struct strbuf *buffer, const char *const *env)
+#ifndef DEFAULT_EDITOR
+#define DEFAULT_EDITOR "vi"
+#endif
+
+const char *git_editor(void)
{
- const char *editor, *terminal;
+ const char *editor = getenv("GIT_EDITOR");
+ const char *terminal = getenv("TERM");
+ int terminal_is_dumb = !terminal || !strcmp(terminal, "dumb");
- editor = getenv("GIT_EDITOR");
if (!editor && editor_program)
editor = editor_program;
- if (!editor)
+ if (!editor && !terminal_is_dumb)
editor = getenv("VISUAL");
if (!editor)
editor = getenv("EDITOR");
- terminal = getenv("TERM");
- if (!editor && (!terminal || !strcmp(terminal, "dumb")))
- return error("Terminal is dumb but no VISUAL nor EDITOR defined.");
+ if (!editor && terminal_is_dumb)
+ return NULL;
+
+ if (!editor)
+ editor = DEFAULT_EDITOR;
+
+ return editor;
+}
+
+int launch_editor(const char *path, struct strbuf *buffer, const char *const *env)
+{
+ const char *editor = git_editor();
if (!editor)
- editor = "vi";
+ return error("Terminal is dumb, but EDITOR unset");
if (strcmp(editor, ":")) {
size_t len = strlen(editor);
const char *args[6];
struct strbuf arg0 = STRBUF_INIT;
- if (strcspn(editor, "$ \t'") != len) {
+ if (strcspn(editor, "|&;<>()$`\\\"' \t\n*?[#~=%") != len) {
/* there are specials */
strbuf_addf(&arg0, "%s \"$@\"", editor);
args[i++] = "sh";
EOF
close $fh;
- my $editor = $ENV{GIT_EDITOR} || $repo->config("core.editor")
- || $ENV{VISUAL} || $ENV{EDITOR} || "vi";
+ chomp(my $editor = run_cmd_pipe(qw(git var GIT_EDITOR)));
system('sh', '-c', $editor.' "$@"', $editor, $hunkfile);
if ($? != 0) {
[eE]*) git_editor "$dotest/final-commit"
action=again ;;
[vV]*) action=again
- LESS=-S ${PAGER:-less} "$dotest/patch" ;;
+ : ${GIT_PAGER=$(git var GIT_PAGER)}
+ : ${LESS=-FRSX}
+ export LESS
+ $GIT_PAGER "$dotest/patch" ;;
*) action=again ;;
esac
done
# Handle interactive edition of files.
my $multiedit;
-my $editor = $ENV{GIT_EDITOR} || Git::config(@repo, "core.editor") || $ENV{VISUAL} || $ENV{EDITOR} || "vi";
+my $editor = Git::command_oneline('var', 'GIT_EDITOR');
+
sub do_edit {
if (defined($multiedit) && !$multiedit) {
map {
}
git_editor() {
- : "${GIT_EDITOR:=$(git config core.editor)}"
- : "${GIT_EDITOR:=${VISUAL:-${EDITOR}}}"
- case "$GIT_EDITOR,$TERM" in
- ,dumb)
- echo >&2 "No editor specified in GIT_EDITOR, core.editor, VISUAL,"
- echo >&2 "or EDITOR. Tried to fall back to vi but terminal is dumb."
- echo >&2 "Please set one of these variables to an appropriate"
- echo >&2 "editor or run $0 with options that will not cause an"
- echo >&2 "editor to be invoked (e.g., -m or -F for git-commit)."
- exit 1
- ;;
- esac
- eval "${GIT_EDITOR:=vi}" '"$@"'
+ if test -z "${GIT_EDITOR:+set}"
+ then
+ GIT_EDITOR="$(git var GIT_EDITOR)" || return $?
+ fi
+
+ eval "$GIT_EDITOR" '"$@"'
}
is_bare_repository () {
close $log_fh or croak $!;
if ($_edit || ($type eq 'tree')) {
- my $editor = $ENV{VISUAL} || $ENV{EDITOR} || 'vi';
- # TODO: strip out spaces, comments, like git-commit.sh
- system($editor, $commit_editmsg);
+ chomp(my $editor = command_oneline(qw(var GIT_EDITOR)));
+ system('sh', '-c', $editor.' "$@"', $editor, $commit_editmsg);
}
rename $commit_editmsg, $commit_msg or croak $!;
{
# adapted from pager.c
sub config_pager {
- $pager ||= $ENV{GIT_PAGER} || $ENV{PAGER};
- if (!defined $pager) {
- $pager = 'less';
- } elsif (length $pager == 0 || $pager eq 'cat') {
+ chomp(my $pager = command_oneline(qw(var GIT_PAGER)));
+ if ($pager eq 'cat') {
$pager = undef;
}
$ENV{GIT_PAGER_IN_USE} = defined($pager);
if ((warn_on_no_name || error_on_no_name) &&
name == git_default_name && env_hint) {
fprintf(stderr, env_hint, au_env, co_env);
- env_hint = NULL; /* warn only once, for "git var -l" */
+ env_hint = NULL; /* warn only once */
}
if (error_on_no_name)
die("empty ident %s <%s> not allowed", name, email);
#include "run-command.h"
#include "sigchain.h"
+#ifndef DEFAULT_PAGER
+#define DEFAULT_PAGER "less"
+#endif
+
/*
* This is split up from the rest of git so that we can do
* something different on Windows.
raise(signo);
}
-void setup_pager(void)
+const char *git_pager(void)
{
- const char *pager = getenv("GIT_PAGER");
+ const char *pager;
if (!isatty(1))
- return;
+ return NULL;
+
+ pager = getenv("GIT_PAGER");
if (!pager) {
if (!pager_program)
git_config(git_default_config, NULL);
if (!pager)
pager = getenv("PAGER");
if (!pager)
- pager = "less";
+ pager = DEFAULT_PAGER;
else if (!*pager || !strcmp(pager, "cat"))
+ pager = NULL;
+
+ return pager;
+}
+
+void setup_pager(void)
+{
+ const char *pager = git_pager();
+
+ if (!pager)
return;
spawned_pager = 1; /* means we are emitting to terminal */
. ./test-lib.sh
-for i in GIT_EDITOR core_editor EDITOR VISUAL vi
+unset EDITOR VISUAL GIT_EDITOR
+
+test_expect_success 'determine default editor' '
+
+ vi=$(TERM=vt100 git var GIT_EDITOR) &&
+ test -n "$vi"
+
+'
+
+if ! expr "$vi" : '^[a-z]*$' >/dev/null
+then
+ vi=
+fi
+
+for i in GIT_EDITOR core_editor EDITOR VISUAL $vi
do
cat >e-$i.sh <<-EOF
#!$SHELL_PATH
EOF
chmod +x e-$i.sh
done
-unset vi
-mv e-vi.sh vi
-unset EDITOR VISUAL GIT_EDITOR
+
+if ! test -z "$vi"
+then
+ mv e-$vi.sh $vi
+fi
test_expect_success setup '
- msg="Hand edited" &&
+ msg="Hand-edited" &&
+ test_commit "$msg" &&
echo "$msg" >expect &&
- git add vi &&
- test_tick &&
- git commit -m "$msg" &&
- git show -s --pretty=oneline |
- sed -e "s/^[0-9a-f]* //" >actual &&
+ git show -s --format=%s > actual &&
diff actual expect
'
fi
'
+test_expect_success 'dumb should prefer EDITOR to VISUAL' '
+
+ EDITOR=./e-EDITOR.sh &&
+ VISUAL=./e-VISUAL.sh &&
+ export EDITOR VISUAL &&
+ git commit --amend &&
+ test "$(git show -s --format=%s)" = "Edited by EDITOR"
+
+'
+
TERM=vt100
export TERM
-for i in vi EDITOR VISUAL core_editor GIT_EDITOR
+for i in $vi EDITOR VISUAL core_editor GIT_EDITOR
do
echo "Edited by $i" >expect
unset EDITOR VISUAL GIT_EDITOR
unset EDITOR VISUAL GIT_EDITOR
git config --unset-all core.editor
-for i in vi EDITOR VISUAL core_editor GIT_EDITOR
+for i in $vi EDITOR VISUAL core_editor GIT_EDITOR
do
echo "Edited by $i" >expect
case "$i" in
test_expect_success \
"amend commit" \
- "VISUAL=./editor git commit --amend"
+ "EDITOR=./editor git commit --amend"
test_expect_success \
"passing -m and -F" \
test_expect_success \
"editing message from other commit" \
"echo 'hula hula' >file && \
- VISUAL=./editor git commit -c HEAD^ -a"
+ EDITOR=./editor git commit -c HEAD^ -a"
test_expect_success \
"message from stdin" \
test_expect_success \
'editor not invoked if -F is given' '
echo "moo" >file &&
- VISUAL=./editor git commit -a -F msg &&
+ EDITOR=./editor git commit -a -F msg &&
git show -s --pretty=format:"%s" | grep -q good &&
echo "quack" >file &&
- echo "Another good message." | VISUAL=./editor git commit -a -F - &&
+ echo "Another good message." | EDITOR=./editor git commit -a -F - &&
git show -s --pretty=format:"%s" | grep -q good
'
# We could just check the head sha1, but checking each commit makes it
TERM=dumb
export LANG LC_ALL PAGER TERM TZ
EDITOR=:
-VISUAL=:
+unset VISUAL
unset GIT_EDITOR
unset AUTHOR_DATE
unset AUTHOR_EMAIL
export GIT_MERGE_VERBOSITY
export GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME
export GIT_COMMITTER_EMAIL GIT_COMMITTER_NAME
-export EDITOR VISUAL
+export EDITOR
GIT_TEST_CMP=${GIT_TEST_CMP:-diff -u}
# Protect ourselves from common misconfiguration to export
test_set_editor () {
FAKE_EDITOR="$1"
export FAKE_EDITOR
- VISUAL='"$FAKE_EDITOR"'
- export VISUAL
+ EDITOR='"$FAKE_EDITOR"'
+ export EDITOR
}
test_tick () {
static const char var_usage[] = "git var [-l | <variable>]";
+static const char *editor(int flag)
+{
+ const char *pgm = git_editor();
+
+ if (!pgm && flag & IDENT_ERROR_ON_NO_NAME)
+ die("Terminal is dumb, but EDITOR unset");
+
+ return pgm;
+}
+
+static const char *pager(int flag)
+{
+ const char *pgm = git_pager();
+
+ if (!pgm)
+ pgm = "cat";
+ return pgm;
+}
+
struct git_var {
const char *name;
const char *(*read)(int);
static struct git_var git_vars[] = {
{ "GIT_COMMITTER_IDENT", git_committer_info },
{ "GIT_AUTHOR_IDENT", git_author_info },
+ { "GIT_EDITOR", editor },
+ { "GIT_PAGER", pager },
{ "", NULL },
};
static void list_vars(void)
{
struct git_var *ptr;
+ const char *val;
+
for (ptr = git_vars; ptr->read; ptr++)
- printf("%s=%s\n", ptr->name, ptr->read(IDENT_WARN_ON_NO_NAME));
+ if ((val = ptr->read(0)))
+ printf("%s=%s\n", ptr->name, val);
}
static const char *read_var(const char *var)