diff options
-rw-r--r-- | Documentation/git-grep.txt | 3 | ||||
-rw-r--r-- | Documentation/git-show-ref.txt | 6 | ||||
-rw-r--r-- | credential-cache.c | 10 | ||||
-rw-r--r-- | diff-lib.c | 2 | ||||
-rw-r--r-- | diff.c | 9 | ||||
-rwxr-xr-x | t/t4010-diff-pathspec.sh | 8 | ||||
-rwxr-xr-x | t/t4034-diff-words.sh | 14 | ||||
-rw-r--r-- | tree-walk.c | 3 | ||||
-rw-r--r-- | unix-socket.c | 104 |
9 files changed, 134 insertions, 25 deletions
diff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt index 15d6711d46..6a8b1e3a7d 100644 --- a/Documentation/git-grep.txt +++ b/Documentation/git-grep.txt @@ -79,6 +79,9 @@ OPTIONS --max-depth <depth>:: For each <pathspec> given on command line, descend at most <depth> levels of directories. A negative value means no limit. + This option is ignored if <pathspec> contains active wildcards. + In other words if "a*" matches a directory named "a*", + "*" is matched literally so --max-depth is still effective. -w:: --word-regexp:: diff --git a/Documentation/git-show-ref.txt b/Documentation/git-show-ref.txt index 3c45895299..fcee0008a9 100644 --- a/Documentation/git-show-ref.txt +++ b/Documentation/git-show-ref.txt @@ -44,7 +44,7 @@ OPTIONS -d:: --dereference:: - Dereference tags into object IDs as well. They will be shown with "^{}" + Dereference tags into object IDs as well. They will be shown with "{caret}{}" appended. -s:: @@ -73,9 +73,9 @@ OPTIONS --exclude-existing[=<pattern>]:: Make 'git show-ref' act as a filter that reads refs from stdin of the - form "^(?:<anything>\s)?<refname>(?:{backslash}{caret}\{\})?$" + form "`{caret}(?:<anything>\s)?<refname>(?:{backslash}{caret}{})?$`" and performs the following actions on each: - (1) strip "^{}" at the end of line if any; + (1) strip "{caret}{}" at the end of line if any; (2) ignore if pattern is provided and does not head-match refname; (3) warn if refname is not a well-formed refname and skip; (4) ignore if refname is a ref that exists in the local repository; diff --git a/credential-cache.c b/credential-cache.c index b15a9a7449..9a03792c7d 100644 --- a/credential-cache.c +++ b/credential-cache.c @@ -71,10 +71,14 @@ static void do_cache(const char *socket, const char *action, int timeout, die_errno("unable to relay credential"); } - if (send_request(socket, &buf) < 0 && (flags & FLAG_SPAWN)) { - spawn_daemon(socket); - if (send_request(socket, &buf) < 0) + if (send_request(socket, &buf) < 0) { + if (errno != ENOENT && errno != ECONNREFUSED) die_errno("unable to connect to cache daemon"); + if (flags & FLAG_SPAWN) { + spawn_daemon(socket); + if (send_request(socket, &buf) < 0) + die_errno("unable to connect to cache daemon"); + } } strbuf_release(&buf); } diff --git a/diff-lib.c b/diff-lib.c index 62f4cd94cf..fc0dff31b5 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -469,6 +469,8 @@ static int diff_cache(struct rev_info *revs, opts.src_index = &the_index; opts.dst_index = NULL; opts.pathspec = &revs->diffopt.pathspec; + opts.pathspec->recursive = 1; + opts.pathspec->max_depth = -1; init_tree_desc(&t, tree->buffer, tree->size); return unpack_trees(1, &t, &opts); @@ -1113,6 +1113,15 @@ static void fn_out_consume(void *priv, char *line, unsigned long len) diff_words_append(line, len, &ecbdata->diff_words->plus); return; + } else if (!prefixcmp(line, "\\ ")) { + /* + * Eat the "no newline at eof" marker as if we + * saw a "+" or "-" line with nothing on it, + * and return without diff_words_flush() to + * defer processing. If this is the end of + * preimage, more "+" lines may come after it. + */ + return; } diff_words_flush(ecbdata); if (ecbdata->diff_words->type == DIFF_WORDS_PORCELAIN) { diff --git a/t/t4010-diff-pathspec.sh b/t/t4010-diff-pathspec.sh index fbc8cd8f05..af5134b70c 100755 --- a/t/t4010-diff-pathspec.sh +++ b/t/t4010-diff-pathspec.sh @@ -48,6 +48,14 @@ test_expect_success \ compare_diff_raw current expected' cat >expected <<\EOF +:100644 100644 766498d93a4b06057a8e49d23f4068f1170ff38f 0a41e115ab61be0328a19b29f18cdcb49338d516 M path1/file1 +EOF +test_expect_success \ + '"*file1" should show path1/file1' \ + 'git diff-index --cached $tree -- "*file1" >current && + compare_diff_raw current expected' + +cat >expected <<\EOF :100644 100644 766498d93a4b06057a8e49d23f4068f1170ff38f 0a41e115ab61be0328a19b29f18cdcb49338d516 M file0 EOF test_expect_success \ diff --git a/t/t4034-diff-words.sh b/t/t4034-diff-words.sh index 6f1e5a2a15..5c2012111c 100755 --- a/t/t4034-diff-words.sh +++ b/t/t4034-diff-words.sh @@ -334,4 +334,18 @@ test_expect_success 'word-diff with diff.sbe' ' word_diff --word-diff=plain ' +test_expect_success 'word-diff with no newline at EOF' ' + cat >expect <<-\EOF && + diff --git a/pre b/post + index 7bf316e..3dd0303 100644 + --- a/pre + +++ b/post + @@ -1 +1 @@ + a a [-a-]{+ab+} a a + EOF + printf "%s" "a a a a a" >pre && + printf "%s" "a a ab a a" >post && + word_diff --word-diff=plain +' + test_done diff --git a/tree-walk.c b/tree-walk.c index f82dba6a1f..492c7cd744 100644 --- a/tree-walk.c +++ b/tree-walk.c @@ -661,6 +661,9 @@ match_wildcards: /* * Match all directories. We'll try to match files * later on. + * max_depth is ignored but we may consider support it + * in future, see + * http://thread.gmane.org/gmane.comp.version-control.git/163757/focus=163840 */ if (ps->recursive && S_ISDIR(entry->mode)) return entry_interesting; diff --git a/unix-socket.c b/unix-socket.c index 84b15099f2..01f119f970 100644 --- a/unix-socket.c +++ b/unix-socket.c @@ -9,48 +9,114 @@ static int unix_stream_socket(void) return fd; } -static void unix_sockaddr_init(struct sockaddr_un *sa, const char *path) +static int chdir_len(const char *orig, int len) +{ + char *path = xmemdupz(orig, len); + int r = chdir(path); + free(path); + return r; +} + +struct unix_sockaddr_context { + char orig_dir[PATH_MAX]; +}; + +static void unix_sockaddr_cleanup(struct unix_sockaddr_context *ctx) +{ + if (!ctx->orig_dir[0]) + return; + /* + * If we fail, we can't just return an error, since we have + * moved the cwd of the whole process, which could confuse calling + * code. We are better off to just die. + */ + if (chdir(ctx->orig_dir) < 0) + die("unable to restore original working directory"); +} + +static int unix_sockaddr_init(struct sockaddr_un *sa, const char *path, + struct unix_sockaddr_context *ctx) { int size = strlen(path) + 1; - if (size > sizeof(sa->sun_path)) - die("socket path is too long to fit in sockaddr"); + + ctx->orig_dir[0] = '\0'; + if (size > sizeof(sa->sun_path)) { + const char *slash = find_last_dir_sep(path); + const char *dir; + + if (!slash) { + errno = ENAMETOOLONG; + return -1; + } + + dir = path; + path = slash + 1; + size = strlen(path) + 1; + if (size > sizeof(sa->sun_path)) { + errno = ENAMETOOLONG; + return -1; + } + + if (!getcwd(ctx->orig_dir, sizeof(ctx->orig_dir))) { + errno = ENAMETOOLONG; + return -1; + } + if (chdir_len(dir, slash - dir) < 0) + return -1; + } + memset(sa, 0, sizeof(*sa)); sa->sun_family = AF_UNIX; memcpy(sa->sun_path, path, size); + return 0; } int unix_stream_connect(const char *path) { - int fd; + int fd, saved_errno; struct sockaddr_un sa; + struct unix_sockaddr_context ctx; - unix_sockaddr_init(&sa, path); - fd = unix_stream_socket(); - if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) { - close(fd); + if (unix_sockaddr_init(&sa, path, &ctx) < 0) return -1; - } + fd = unix_stream_socket(); + if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) + goto fail; + unix_sockaddr_cleanup(&ctx); return fd; + +fail: + saved_errno = errno; + unix_sockaddr_cleanup(&ctx); + close(fd); + errno = saved_errno; + return -1; } int unix_stream_listen(const char *path) { - int fd; + int fd, saved_errno; struct sockaddr_un sa; + struct unix_sockaddr_context ctx; - unix_sockaddr_init(&sa, path); + if (unix_sockaddr_init(&sa, path, &ctx) < 0) + return -1; fd = unix_stream_socket(); unlink(path); - if (bind(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) { - close(fd); - return -1; - } + if (bind(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) + goto fail; - if (listen(fd, 5) < 0) { - close(fd); - return -1; - } + if (listen(fd, 5) < 0) + goto fail; + unix_sockaddr_cleanup(&ctx); return fd; + +fail: + saved_errno = errno; + unix_sockaddr_cleanup(&ctx); + close(fd); + errno = saved_errno; + return -1; } |