diff-index.c: "git diff" has no need to read blob from the standard input
Only "diff --no-index -" does. Bolting the logic into the low-level function diff_populate_filespec() was a layering violation from day one. Move populate_from_stdin() function out of the generic diff.c to its only user, diff-index.c. Also make sure "-" from the command line stays a special token "read from the standard input", even if we later decide to sanitize the result from prefix_filename() function in a few obvious ways, e.g. removing unnecessary "./" prefix, duplicated slashes "//" in the middle, etc. Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
3b069b1beb
commit
4682d8521c
@ -32,6 +32,13 @@ static int read_directory(const char *path, struct string_list *list)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This should be "(standard input)" or something, but it will
|
||||||
|
* probably expose many more breakages in the way no-index code
|
||||||
|
* is bolted onto the diff callchain.
|
||||||
|
*/
|
||||||
|
static const char file_from_standard_input[] = "-";
|
||||||
|
|
||||||
static int get_mode(const char *path, int *mode)
|
static int get_mode(const char *path, int *mode)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
@ -42,7 +49,7 @@ static int get_mode(const char *path, int *mode)
|
|||||||
else if (!strcasecmp(path, "nul"))
|
else if (!strcasecmp(path, "nul"))
|
||||||
*mode = 0;
|
*mode = 0;
|
||||||
#endif
|
#endif
|
||||||
else if (!strcmp(path, "-"))
|
else if (path == file_from_standard_input)
|
||||||
*mode = create_ce_mode(0666);
|
*mode = create_ce_mode(0666);
|
||||||
else if (lstat(path, &st))
|
else if (lstat(path, &st))
|
||||||
return error("Could not access '%s'", path);
|
return error("Could not access '%s'", path);
|
||||||
@ -51,6 +58,36 @@ static int get_mode(const char *path, int *mode)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int populate_from_stdin(struct diff_filespec *s)
|
||||||
|
{
|
||||||
|
struct strbuf buf = STRBUF_INIT;
|
||||||
|
size_t size = 0;
|
||||||
|
|
||||||
|
if (strbuf_read(&buf, 0, 0) < 0)
|
||||||
|
return error("error while reading from stdin %s",
|
||||||
|
strerror(errno));
|
||||||
|
|
||||||
|
s->should_munmap = 0;
|
||||||
|
s->data = strbuf_detach(&buf, &size);
|
||||||
|
s->size = size;
|
||||||
|
s->should_free = 1;
|
||||||
|
s->is_stdin = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct diff_filespec *noindex_filespec(const char *name, int mode)
|
||||||
|
{
|
||||||
|
struct diff_filespec *s;
|
||||||
|
|
||||||
|
if (!name)
|
||||||
|
name = "/dev/null";
|
||||||
|
s = alloc_filespec(name);
|
||||||
|
fill_filespec(s, null_sha1, mode);
|
||||||
|
if (name == file_from_standard_input)
|
||||||
|
populate_from_stdin(s);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
static int queue_diff(struct diff_options *o,
|
static int queue_diff(struct diff_options *o,
|
||||||
const char *name1, const char *name2)
|
const char *name1, const char *name2)
|
||||||
{
|
{
|
||||||
@ -135,15 +172,8 @@ static int queue_diff(struct diff_options *o,
|
|||||||
tmp_c = name1; name1 = name2; name2 = tmp_c;
|
tmp_c = name1; name1 = name2; name2 = tmp_c;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!name1)
|
d1 = noindex_filespec(name1, mode1);
|
||||||
name1 = "/dev/null";
|
d2 = noindex_filespec(name2, mode2);
|
||||||
if (!name2)
|
|
||||||
name2 = "/dev/null";
|
|
||||||
d1 = alloc_filespec(name1);
|
|
||||||
d2 = alloc_filespec(name2);
|
|
||||||
fill_filespec(d1, null_sha1, mode1);
|
|
||||||
fill_filespec(d2, null_sha1, mode2);
|
|
||||||
|
|
||||||
diff_queue(&diff_queued_diff, d1, d2);
|
diff_queue(&diff_queued_diff, d1, d2);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -238,7 +268,7 @@ void diff_no_index(struct rev_info *revs,
|
|||||||
* stdin should be spelled as "-"; if you have
|
* stdin should be spelled as "-"; if you have
|
||||||
* path that is "-", spell it as "./-".
|
* path that is "-", spell it as "./-".
|
||||||
*/
|
*/
|
||||||
p = p;
|
p = file_from_standard_input;
|
||||||
else if (prefixlen)
|
else if (prefixlen)
|
||||||
p = xstrdup(prefix_filename(prefix, prefixlen, p));
|
p = xstrdup(prefix_filename(prefix, prefixlen, p));
|
||||||
paths[i] = p;
|
paths[i] = p;
|
||||||
|
21
diff.c
21
diff.c
@ -2426,22 +2426,6 @@ static int reuse_worktree_file(const char *name, const unsigned char *sha1, int
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int populate_from_stdin(struct diff_filespec *s)
|
|
||||||
{
|
|
||||||
struct strbuf buf = STRBUF_INIT;
|
|
||||||
size_t size = 0;
|
|
||||||
|
|
||||||
if (strbuf_read(&buf, 0, 0) < 0)
|
|
||||||
return error("error while reading from stdin %s",
|
|
||||||
strerror(errno));
|
|
||||||
|
|
||||||
s->should_munmap = 0;
|
|
||||||
s->data = strbuf_detach(&buf, &size);
|
|
||||||
s->size = size;
|
|
||||||
s->should_free = 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int diff_populate_gitlink(struct diff_filespec *s, int size_only)
|
static int diff_populate_gitlink(struct diff_filespec *s, int size_only)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
@ -2491,9 +2475,6 @@ int diff_populate_filespec(struct diff_filespec *s, int size_only)
|
|||||||
struct stat st;
|
struct stat st;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
if (!strcmp(s->path, "-"))
|
|
||||||
return populate_from_stdin(s);
|
|
||||||
|
|
||||||
if (lstat(s->path, &st) < 0) {
|
if (lstat(s->path, &st) < 0) {
|
||||||
if (errno == ENOENT) {
|
if (errno == ENOENT) {
|
||||||
err_empty:
|
err_empty:
|
||||||
@ -2855,7 +2836,7 @@ static void diff_fill_sha1_info(struct diff_filespec *one)
|
|||||||
if (DIFF_FILE_VALID(one)) {
|
if (DIFF_FILE_VALID(one)) {
|
||||||
if (!one->sha1_valid) {
|
if (!one->sha1_valid) {
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (!strcmp(one->path, "-")) {
|
if (one->is_stdin) {
|
||||||
hashcpy(one->sha1, null_sha1);
|
hashcpy(one->sha1, null_sha1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,7 @@ struct diff_filespec {
|
|||||||
unsigned should_free : 1; /* data should be free()'ed */
|
unsigned should_free : 1; /* data should be free()'ed */
|
||||||
unsigned should_munmap : 1; /* data should be munmap()'ed */
|
unsigned should_munmap : 1; /* data should be munmap()'ed */
|
||||||
unsigned dirty_submodule : 2; /* For submodules: its work tree is dirty */
|
unsigned dirty_submodule : 2; /* For submodules: its work tree is dirty */
|
||||||
|
unsigned is_stdin : 1;
|
||||||
#define DIRTY_SUBMODULE_UNTRACKED 1
|
#define DIRTY_SUBMODULE_UNTRACKED 1
|
||||||
#define DIRTY_SUBMODULE_MODIFIED 2
|
#define DIRTY_SUBMODULE_MODIFIED 2
|
||||||
|
|
||||||
|
@ -458,4 +458,16 @@ test_expect_success 'amend can copy notes' '
|
|||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'commit a file whose name is a dash' '
|
||||||
|
git reset --hard &&
|
||||||
|
for i in 1 2 3 4 5
|
||||||
|
do
|
||||||
|
echo $i
|
||||||
|
done >./- &&
|
||||||
|
git add ./- &&
|
||||||
|
test_tick &&
|
||||||
|
git commit -m "add dash" >output </dev/null &&
|
||||||
|
test_i18ngrep " changed, 5 insertions" output
|
||||||
|
'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
Loading…
Reference in New Issue
Block a user