summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/git-grep.txt3
-rw-r--r--Documentation/git-show-ref.txt6
-rw-r--r--credential-cache.c10
-rw-r--r--diff-lib.c2
-rw-r--r--diff.c9
-rwxr-xr-xt/t4010-diff-pathspec.sh8
-rwxr-xr-xt/t4034-diff-words.sh14
-rw-r--r--tree-walk.c3
-rw-r--r--unix-socket.c104
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);
diff --git a/diff.c b/diff.c
index 374ecf3b48..7e154265f7 100644
--- a/diff.c
+++ b/diff.c
@@ -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;
}