git status: show relative paths when run in a subdirectory

To show the relative paths, the function formerly called quote_crlf()
(now called quote_path()) takes the prefix as an additional argument.

While at it, the static buffers were replaced by strbufs.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Johannes Schindelin 2007-11-11 17:35:41 +00:00 коммит произвёл Junio C Hamano
Родитель d37d320386
Коммит 367c98866c
5 изменённых файлов: 146 добавлений и 29 удалений

Просмотреть файл

@ -118,11 +118,12 @@ static char *prepare_index(const char **files, const char *prefix)
return next_index_lock->filename;
}
static int run_status(FILE *fp, const char *index_file)
static int run_status(FILE *fp, const char *index_file, const char *prefix)
{
struct wt_status s;
wt_status_prepare(&s);
s.prefix = prefix;
if (amend) {
s.amend = 1;
@ -140,7 +141,7 @@ static int run_status(FILE *fp, const char *index_file)
static const char sign_off_header[] = "Signed-off-by: ";
static int prepare_log_message(const char *index_file)
static int prepare_log_message(const char *index_file, const char *prefix)
{
struct stat statbuf;
int commitable;
@ -216,7 +217,7 @@ static int prepare_log_message(const char *index_file)
if (only_include_assumed)
fprintf(fp, "# %s\n", only_include_assumed);
commitable = run_status(fp, index_file);
commitable = run_status(fp, index_file, prefix);
fclose(fp);
@ -409,7 +410,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)
index_file = prepare_index(argv, prefix);
commitable = run_status(stdout, index_file);
commitable = run_status(stdout, index_file, prefix);
rollback_lock_file(&lock_file);
@ -503,8 +504,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
if (!no_verify && run_hook(index_file, "pre-commit", NULL))
exit(1);
if (!prepare_log_message(index_file) && !in_merge) {
run_status(stdout, index_file);
if (!prepare_log_message(index_file, prefix) && !in_merge) {
run_status(stdout, index_file, prefix);
unlink(commit_editmsg);
return 1;
}

Просмотреть файл

@ -14,6 +14,7 @@ int cmd_runstatus(int argc, const char **argv, const char *prefix)
git_config(git_status_config);
wt_status_prepare(&s);
s.prefix = prefix;
for (i = 1; i < argc; i++) {
if (!strcmp(argv[i], "--color"))

91
t/t7502-status.sh Executable file
Просмотреть файл

@ -0,0 +1,91 @@
#!/bin/sh
#
# Copyright (c) 2007 Johannes E. Schindelin
#
test_description='git-status'
. ./test-lib.sh
test_expect_success 'setup' '
: > tracked &&
: > modified &&
mkdir dir1 &&
: > dir1/tracked &&
: > dir1/modified &&
mkdir dir2 &&
: > dir1/tracked &&
: > dir1/modified &&
git add . &&
test_tick &&
git commit -m initial &&
: > untracked &&
: > dir1/untracked &&
: > dir2/untracked &&
echo 1 > dir1/modified &&
echo 2 > dir2/modified &&
echo 3 > dir2/added &&
git add dir2/added
'
cat > expect << \EOF
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: dir2/added
#
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
#
# modified: dir1/modified
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# dir1/untracked
# dir2/modified
# dir2/untracked
# expect
# output
# untracked
EOF
test_expect_success 'status' '
git status > output &&
git diff expect output
'
cat > expect << \EOF
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: ../dir2/added
#
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
#
# modified: ../dir1/modified
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# untracked
# ../dir2/modified
# ../dir2/untracked
# ../expect
# ../output
# ../untracked
EOF
test_expect_success 'status with relative paths' '
(cd dir1 && git status) > output &&
git diff expect output
'
test_done

Просмотреть файл

@ -81,33 +81,46 @@ static void wt_status_print_trailer(struct wt_status *s)
color_fprintf_ln(s->fp, color(WT_STATUS_HEADER), "#");
}
static const char *quote_crlf(const char *in, char *buf, size_t sz)
static char *quote_path(const char *in, int len,
struct strbuf *out, const char *prefix)
{
const char *scan;
char *out;
const char *ret = in;
if (len > 0)
strbuf_grow(out, len);
strbuf_setlen(out, 0);
for (scan = in, out = buf; *scan; scan++) {
int ch = *scan;
int quoted;
if (prefix) {
int off = 0;
while (prefix[off] && off < len && prefix[off] == in[off])
if (prefix[off] == '/') {
prefix += off + 1;
in += off + 1;
len -= off + 1;
off = 0;
} else
off++;
for (; *prefix; prefix++)
if (*prefix == '/')
strbuf_addstr(out, "../");
}
for (; (len < 0 && *in) || len > 0; in++, len--) {
int ch = *in;
switch (ch) {
case '\n':
quoted = 'n';
strbuf_addstr(out, "\\n");
break;
case '\r':
quoted = 'r';
strbuf_addstr(out, "\\r");
break;
default:
*out++ = ch;
strbuf_addch(out, ch);
continue;
}
*out++ = '\\';
*out++ = quoted;
ret = buf;
}
*out = '\0';
return ret;
return out->buf;
}
static void wt_status_print_filepair(struct wt_status *s,
@ -115,10 +128,12 @@ static void wt_status_print_filepair(struct wt_status *s,
{
const char *c = color(t);
const char *one, *two;
char onebuf[PATH_MAX], twobuf[PATH_MAX];
struct strbuf onebuf, twobuf;
one = quote_crlf(p->one->path, onebuf, sizeof(onebuf));
two = quote_crlf(p->two->path, twobuf, sizeof(twobuf));
strbuf_init(&onebuf, 0);
strbuf_init(&twobuf, 0);
one = quote_path(p->one->path, -1, &onebuf, s->prefix);
two = quote_path(p->two->path, -1, &twobuf, s->prefix);
color_fprintf(s->fp, color(WT_STATUS_HEADER), "#\t");
switch (p->status) {
@ -150,6 +165,8 @@ static void wt_status_print_filepair(struct wt_status *s,
die("bug: unhandled diff status %c", p->status);
}
fprintf(s->fp, "\n");
strbuf_release(&onebuf);
strbuf_release(&twobuf);
}
static void wt_status_print_updated_cb(struct diff_queue_struct *q,
@ -204,8 +221,9 @@ static void wt_read_cache(struct wt_status *s)
static void wt_status_print_initial(struct wt_status *s)
{
int i;
char buf[PATH_MAX];
struct strbuf buf;
strbuf_init(&buf, 0);
wt_read_cache(s);
if (active_nr) {
s->commitable = 1;
@ -214,11 +232,12 @@ static void wt_status_print_initial(struct wt_status *s)
for (i = 0; i < active_nr; i++) {
color_fprintf(s->fp, color(WT_STATUS_HEADER), "#\t");
color_fprintf_ln(s->fp, color(WT_STATUS_UPDATED), "new file: %s",
quote_crlf(active_cache[i]->name,
buf, sizeof(buf)));
quote_path(active_cache[i]->name, -1,
&buf, s->prefix));
}
if (active_nr)
wt_status_print_trailer(s);
strbuf_release(&buf);
}
static void wt_status_print_updated(struct wt_status *s)
@ -252,7 +271,9 @@ static void wt_status_print_untracked(struct wt_status *s)
struct dir_struct dir;
int i;
int shown_header = 0;
struct strbuf buf;
strbuf_init(&buf, 0);
memset(&dir, 0, sizeof(dir));
if (!s->untracked) {
@ -284,9 +305,11 @@ static void wt_status_print_untracked(struct wt_status *s)
shown_header = 1;
}
color_fprintf(s->fp, color(WT_STATUS_HEADER), "#\t");
color_fprintf_ln(s->fp, color(WT_STATUS_UNTRACKED), "%.*s",
ent->len, ent->name);
color_fprintf_ln(s->fp, color(WT_STATUS_UNTRACKED), "%s",
quote_path(ent->name, ent->len,
&buf, s->prefix));
}
strbuf_release(&buf);
}
static void wt_status_print_verbose(struct wt_status *s)

Просмотреть файл

@ -23,6 +23,7 @@ struct wt_status {
int workdir_untracked;
const char *index_file;
FILE *fp;
const char *prefix;
};
int git_status_config(const char *var, const char *value);