Compare commits

...

23 Commits

Author SHA1 Message Date
cf8899d285 Git 2.13.4
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-08-01 11:45:17 -07:00
c94ef19041 Preparation for 2.13.4 continues
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-07-31 13:52:40 -07:00
0baf0b839b Merge branch 'ks/doc-fixes' into maint
Doc clean-up.

* ks/doc-fixes:
  doc: reformat the paragraph containing the 'cut-line'
  doc: camelCase the i18n config variables to improve readability
2017-07-31 13:51:06 -07:00
42dbdef1ca Merge branch 'jk/test-copy-bytes-fix' into maint
A test fix.

* jk/test-copy-bytes-fix:
  t: handle EOF in test_copy_bytes()
2017-07-31 13:51:06 -07:00
c6767f45e3 Merge branch 'pw/unquote-path-in-git-pm' into maint
Code refactoring.

* pw/unquote-path-in-git-pm:
  t9700: add tests for Git::unquote_path()
  Git::unquote_path(): throw an exception on bad path
  Git::unquote_path(): handle '\a'
  add -i: move unquote_path() to Git.pm
2017-07-31 13:51:05 -07:00
133578a020 Merge branch 'jk/gc-pre-detach-under-hook' into maint
We run an early part of "git gc" that deals with refs before
daemonising (and not under lock) even when running a background
auto-gc, which caused multiple gc processes attempting to run the
early part at the same time.  This is now prevented by running the
early part also under the GC lock.

* jk/gc-pre-detach-under-hook:
  gc: run pre-detach operations under lock
2017-07-31 13:51:05 -07:00
309ff914d5 Merge branch 'jn/hooks-pre-rebase-sample-fix' into maint
Code clean-up, that makes us in sync with Debian by one patch.

* jn/hooks-pre-rebase-sample-fix:
  pre-rebase hook: capture documentation in a <<here document
2017-07-31 13:51:05 -07:00
4f77f618d9 Merge branch 'rs/progress-overall-throughput-at-the-end' into maint
The progress meter did not give a useful output when we haven't had
0.5 seconds to measure the throughput during the interval.  Instead
show the overall throughput rate at the end, which is a much more
useful number.

* rs/progress-overall-throughput-at-the-end:
  progress: show overall rate in last update
2017-07-31 13:51:04 -07:00
49f1e2eb1b Merge branch 'tb/push-to-cygwin-unc-path' into maint
On Cygwin, similar to Windows, "git push //server/share/repository"
ought to mean a repository on a network share that can be accessed
locally, but this did not work correctly due to stripping the double
slashes at the beginning.

This may need to be heavily tested before it gets unleashed to the
wild, as the change is at a fairly low-level code and would affect
not just the code to decide if the push destination is local.  There
may be unexpected fallouts in the path normalization.

* tb/push-to-cygwin-unc-path:
  cygwin: allow pushing to UNC paths
2017-07-31 13:51:04 -07:00
bc2c50fc2c Merge branch 'rs/apply-avoid-over-reading' into maint
Code cleanup.

* rs/apply-avoid-over-reading:
  apply: use strcmp(3) for comparing strings in gitdiff_verify_name()
  apply: use starts_with() in gitdiff_verify_name()
2017-07-31 13:51:04 -07:00
3a33fe5c97 doc: reformat the paragraph containing the 'cut-line'
The paragraph that describes the 'scissors' cleanup mode of
'commit' had the 'cut-line' in the middle of a sentence. This
made it possible for the line to get wrapped on smaler windows.
This shouldn't be the case as it makes it hard for the user to
understand the structure of the cut-line.

Reformat the pragraph to make the 'cut-line' stand on a line of
it's own thus distinguishing it from the rest of the paragraph.
This further prevents it from getting wrapped to some extent.

Signed-off-by: Kaartic Sivaraam <kaarticsivaraam91196@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-07-18 15:04:49 -07:00
95791be750 doc: camelCase the i18n config variables to improve readability
The i18n config variable used weren't readable as they were in
the crude form of how git stores/uses it's config variables.

Improve it's readability by replacing them with camelCased versions
of config variables as it doesn't have any impact on it's usage.

Signed-off-by: Kaartic Sivaraam <kaarticsivaraam91196@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-07-17 15:11:26 -07:00
f7f6dc340e t: handle EOF in test_copy_bytes()
The test_copy_bytes() function claims to read up to N bytes,
or until it gets EOF. But we never handle EOF in our loop,
and a short input will cause perl to go into an infinite
loop of read() getting zero bytes.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-07-17 14:55:43 -07:00
c45af94dbc gc: run pre-detach operations under lock
We normally try to avoid having two auto-gc operations run
at the same time, because it wastes resources. This was done
long ago in 64a99eb47 (gc: reject if another gc is running,
unless --force is given, 2013-08-08).

When we do a detached auto-gc, we run the ref-related
commands _before_ detaching, to avoid confusing lock
contention. This was done by 62aad1849 (gc --auto: do not
lock refs in the background, 2014-05-25).

These two features do not interact well. The pre-detach
operations are run before we check the gc.pid lock, meaning
that on a busy repository we may run many of them
concurrently. Ideally we'd take the lock before spawning any
operations, and hold it for the duration of the program.

This is tricky, though, with the way the pid-file interacts
with the daemonize() process.  Other processes will check
that the pid recorded in the pid-file still exists. But
detaching causes us to fork and continue running under a
new pid. So if we take the lock before detaching, the
pid-file will have a bogus pid in it. We'd have to go back
and update it with the new pid after detaching. We'd also
have to play some tricks with the tempfile subsystem to
tweak the "owner" field, so that the parent process does not
clean it up on exit, but the child process does.

Instead, we can do something a bit simpler: take the lock
only for the duration of the pre-detach work, then detach,
then take it again for the post-detach work. Technically,
this means that the post-detach lock could lose to another
process doing pre-detach work. But in the long run this
works out.

That second process would then follow-up by doing
post-detach work. Unless it was in turn blocked by a third
process doing pre-detach work, and so on. This could in
theory go on indefinitely, as the pre-detach work does not
repack, and so need_to_gc() will continue to trigger.  But
in each round we are racing between the pre- and post-detach
locks. Eventually, one of the post-detach locks will win the
race and complete the full gc. So in the worst case, we may
racily repeat the pre-detach work, but we would never do so
simultaneously (it would happen via a sequence of serialized
race-wins).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-07-12 09:41:04 -07:00
8db1ae5740 pre-rebase hook: capture documentation in a <<here document
Without this change, the sample hook does not pass a syntax check
(sh -n):

  $ sh -n hooks--pre-rebase.sample
  hooks--pre-rebase.sample: line 101: syntax error near unexpected token `('
  hooks--pre-rebase.sample: line 101: `   merged into it again (either directly or indirectly).'

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-07-11 08:56:33 -07:00
0fae1e072a progress: show overall rate in last update
The values in struct throughput are only updated every 0.5 seconds.  If
we're all done before that time span then the final update will show a
rate of 0 bytes/s, which is misleading if some bytes had been handled.
Remember the start time and show the total throughput instead.

And avoid division by zero by enforcing a minimum time span value of 1
(unit: 1/1024th of a second).  That makes the resulting rate an
underestimation, but it's closer to the actual value than the currently
shown 0 bytes/s.

Reported-by: 積丹尼 Dan Jacobson <jidanni@jidanni.org>
Signed-off-by: Rene Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-07-09 09:54:20 -07:00
2d105451c0 apply: use strcmp(3) for comparing strings in gitdiff_verify_name()
We don't know the length of the C string "another".  It could be
shorter than "name", which we compare it to using memchr(3).  Call
strcmp(3) instead to avoid running over the end of the former, and
get rid of a strlen(3) call as a bonus.

Signed-off-by: Rene Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-07-09 09:30:42 -07:00
496f256989 cygwin: allow pushing to UNC paths
cygwin can use an UNC path like //server/share/repo

 $ cd //server/share/dir
 $ mkdir test
 $ cd test
 $ git init --bare

 However, when we try to push from a local Git repository to this repo,
 there is a problem: Git converts the leading "//" into a single "/".

 As cygwin handles an UNC path so well, Git can support them better:

 - Introduce cygwin_offset_1st_component() which keeps the leading "//",
   similar to what Git for Windows does.

 - Move CYGWIN out of the POSIX in the tests for path normalization in t0060

Signed-off-by: Torsten Bögershausen <tboegi@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-07-05 14:01:03 -07:00
8bc172e5f2 apply: use starts_with() in gitdiff_verify_name()
Avoid running over the end of line -- a C string whose length is not
known to this function -- by using starts_with() instead of memcmp(3)
for checking if it starts with "/dev/null".  Also simply include the
newline in the string constant to compare against.  Drop a comment that
just states the obvious.

Signed-off-by: Rene Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-07-01 10:39:51 -07:00
3f9c637ec7 t9700: add tests for Git::unquote_path()
Check that unquote_path() handles spaces and escape sequences
properly.

Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-06-30 08:05:15 -07:00
d5f28b7241 Git::unquote_path(): throw an exception on bad path
This is what the other routines in Git.pm do if there's an error.

Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-06-30 08:04:59 -07:00
4cebfac944 Git::unquote_path(): handle '\a'
unquote_path() does not handle quoted paths containing '\a',
even though quote.c::unquote_c_style() does, and quote.c:sq_lookup[]
tells quote.c::sq_must_quote() that '\007' must be quoted as '\a'.

Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-06-30 08:02:43 -07:00
1d542a5487 add -i: move unquote_path() to Git.pm
Move unquote_path() from git-add--interactive to Git.pm so it can be
used by other scripts. Note this is a straight copy, it does not
handle '\a'. That will be fixed in the next commit.

Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-06-30 08:02:20 -07:00
18 changed files with 155 additions and 63 deletions

View File

@ -8,3 +8,21 @@ Fixes since v2.13.3
* A recent update broke an alias that contained an uppercase letter,
which has been fixed.
* On Cygwin, similar to Windows, "git push //server/share/repository"
ought to mean a repository on a network share that can be accessed
locally, but this did not work correctly due to stripping the double
slashes at the beginning.
* The progress meter did not give a useful output when we haven't had
0.5 seconds to measure the throughput during the interval. Instead
show the overall throughput rate at the end, which is a much more
useful number.
* We run an early part of "git gc" that deals with refs before
daemonising (and not under lock) even when running a background
auto-gc, which caused multiple gc processes attempting to run the
early part at the same time. This is now prevented by running the
early part also under the GC lock.
Also contains a handful of small code and documentation clean-ups.

View File

@ -196,11 +196,12 @@ whitespace::
verbatim::
Do not change the message at all.
scissors::
Same as `whitespace`, except that everything from (and
including) the line
"`# ------------------------ >8 ------------------------`"
is truncated if the message is to be edited. "`#`" can be
customized with core.commentChar.
Same as `whitespace` except that everything from (and including)
the line found below is truncated, if the message is to be edited.
"`#`" can be customized with core.commentChar.
# ------------------------ >8 ------------------------
default::
Same as `strip` if the message is to be edited.
Otherwise `whitespace`.

View File

@ -42,11 +42,11 @@ mind.
+
------------
[i18n]
commitencoding = ISO-8859-1
commitEncoding = ISO-8859-1
------------
+
Commit objects created with the above setting record the value
of `i18n.commitencoding` in its `encoding` header. This is to
of `i18n.commitEncoding` in its `encoding` header. This is to
help other people who look at them later. Lack of this header
implies that the commit log message is encoded in UTF-8.
@ -54,15 +54,15 @@ implies that the commit log message is encoded in UTF-8.
`encoding` header of a commit object, and try to re-code the
log message into UTF-8 unless otherwise specified. You can
specify the desired output encoding with
`i18n.logoutputencoding` in `.git/config` file, like this:
`i18n.logOutputEncoding` in `.git/config` file, like this:
+
------------
[i18n]
logoutputencoding = ISO-8859-1
logOutputEncoding = ISO-8859-1
------------
+
If you do not have this configuration variable, the value of
`i18n.commitencoding` is used instead.
`i18n.commitEncoding` is used instead.
Note that we deliberately chose not to re-code the commit log
message when a commit is made to force UTF-8 at the commit

View File

@ -1,7 +1,7 @@
#!/bin/sh
GVF=GIT-VERSION-FILE
DEF_VER=v2.13.3
DEF_VER=v2.13.4
LF='
'

View File

@ -972,13 +972,12 @@ static int gitdiff_verify_name(struct apply_state *state,
}
if (*name) {
int len = strlen(*name);
char *another;
if (isnull)
return error(_("git apply: bad git-diff - expected /dev/null, got %s on line %d"),
*name, state->linenr);
another = find_name(state, line, NULL, state->p_value, TERM_TAB);
if (!another || memcmp(another, *name, len + 1)) {
if (!another || strcmp(another, *name)) {
free(another);
return error((side == DIFF_NEW_NAME) ?
_("git apply: bad git-diff - inconsistent new filename on line %d") :
@ -986,8 +985,7 @@ static int gitdiff_verify_name(struct apply_state *state,
}
free(another);
} else {
/* expect "/dev/null" */
if (memcmp("/dev/null", line, 9) || line[9] != '\n')
if (!starts_with(line, "/dev/null\n"))
return error(_("git apply: bad git-diff - expected /dev/null on line %d"), state->linenr);
}

View File

@ -413,8 +413,12 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
if (report_last_gc_error())
return -1;
if (lock_repo_for_gc(force, &pid))
return 0;
if (gc_before_repack())
return -1;
delete_tempfile(&pidfile);
/*
* failure to daemonize is ok, we'll continue
* in foreground

19
compat/cygwin.c Normal file
View File

@ -0,0 +1,19 @@
#include "../git-compat-util.h"
#include "../cache.h"
int cygwin_offset_1st_component(const char *path)
{
const char *pos = path;
/* unc paths */
if (is_dir_sep(pos[0]) && is_dir_sep(pos[1])) {
/* skip server name */
pos = strchr(pos + 2, '/');
if (!pos)
return 0; /* Error: malformed unc path */
do {
pos++;
} while (*pos && pos[0] != '/');
}
return pos + is_dir_sep(*pos) - path;
}

2
compat/cygwin.h Normal file
View File

@ -0,0 +1,2 @@
int cygwin_offset_1st_component(const char *path);
#define offset_1st_component cygwin_offset_1st_component

View File

@ -181,6 +181,7 @@ ifeq ($(uname_O),Cygwin)
UNRELIABLE_FSTAT = UnfortunatelyYes
SPARSE_FLAGS = -isystem /usr/include/w32api -Wno-one-bit-signed-bitfield
OBJECT_CREATION_USES_RENAMES = UnfortunatelyNeedsTo
COMPAT_OBJS += compat/cygwin.o
endif
ifeq ($(uname_S),FreeBSD)
NEEDS_LIBICONV = YesPlease

View File

@ -3,7 +3,7 @@
use 5.008;
use strict;
use warnings;
use Git;
use Git qw(unquote_path);
use Git::I18N;
binmode(STDOUT, ":raw");
@ -175,47 +175,6 @@ if (!defined $GIT_DIR) {
}
chomp($GIT_DIR);
my %cquote_map = (
"b" => chr(8),
"t" => chr(9),
"n" => chr(10),
"v" => chr(11),
"f" => chr(12),
"r" => chr(13),
"\\" => "\\",
"\042" => "\042",
);
sub unquote_path {
local ($_) = @_;
my ($retval, $remainder);
if (!/^\042(.*)\042$/) {
return $_;
}
($_, $retval) = ($1, "");
while (/^([^\\]*)\\(.*)$/) {
$remainder = $2;
$retval .= $1;
for ($remainder) {
if (/^([0-3][0-7][0-7])(.*)$/) {
$retval .= chr(oct($1));
$_ = $2;
last;
}
if (/^([\\\042btnvfr])(.*)$/) {
$retval .= $cquote_map{$1};
$_ = $2;
last;
}
# This is malformed -- just return it as-is for now.
return $_[0];
}
$_ = $remainder;
}
$retval .= $_;
return $retval;
}
sub refresh {
my $fh;
open $fh, 'git update-index --refresh |'

View File

@ -189,6 +189,9 @@
#include <sys/sysctl.h>
#endif
#if defined(__CYGWIN__)
#include "compat/cygwin.h"
#endif
#if defined(__MINGW32__)
/* pull in Windows compatibility stuff */
#include "compat/mingw.h"

View File

@ -61,7 +61,8 @@ require Exporter;
remote_refs prompt
get_tz_offset get_record
credential credential_read credential_write
temp_acquire temp_is_locked temp_release temp_reset temp_path);
temp_acquire temp_is_locked temp_release temp_reset temp_path
unquote_path);
=head1 DESCRIPTION
@ -1451,6 +1452,57 @@ sub prefix_lines {
return $string;
}
=item unquote_path ( PATH )
Unquote a quoted path containing c-escapes as returned by ls-files etc.
when not using -z or when parsing the output of diff -u.
=cut
{
my %cquote_map = (
"a" => chr(7),
"b" => chr(8),
"t" => chr(9),
"n" => chr(10),
"v" => chr(11),
"f" => chr(12),
"r" => chr(13),
"\\" => "\\",
"\042" => "\042",
);
sub unquote_path {
local ($_) = @_;
my ($retval, $remainder);
if (!/^\042(.*)\042$/) {
return $_;
}
($_, $retval) = ($1, "");
while (/^([^\\]*)\\(.*)$/) {
$remainder = $2;
$retval .= $1;
for ($remainder) {
if (/^([0-3][0-7][0-7])(.*)$/) {
$retval .= chr(oct($1));
$_ = $2;
last;
}
if (/^([\\\042abtnvfr])(.*)$/) {
$retval .= $cquote_map{$1};
$_ = $2;
last;
}
# This is malformed
throw Error::Simple("invalid quoted path $_[0]");
}
$_ = $remainder;
}
$retval .= $_;
return $retval;
}
}
=item get_comment_line_char ( )
Gets the core.commentchar configuration value.

View File

@ -36,6 +36,7 @@ struct progress {
unsigned delay;
unsigned delayed_percent_treshold;
struct throughput *throughput;
uint64_t start_ns;
};
static volatile sig_atomic_t progress_update;
@ -221,6 +222,7 @@ struct progress *start_progress_delay(const char *title, unsigned total,
progress->delayed_percent_treshold = percent_treshold;
progress->delay = delay;
progress->throughput = NULL;
progress->start_ns = getnanotime();
set_progress_signal();
return progress;
}
@ -247,8 +249,10 @@ void stop_progress_msg(struct progress **p_progress, const char *msg)
struct throughput *tp = progress->throughput;
if (tp) {
unsigned int rate = !tp->avg_misecs ? 0 :
tp->avg_bytes / tp->avg_misecs;
uint64_t now_ns = getnanotime();
unsigned int misecs, rate;
misecs = ((now_ns - progress->start_ns) * 4398) >> 32;
rate = tp->curr_total / (misecs ? misecs : 1);
throughput_string(&tp->display, tp->curr_total, rate);
}
progress_update = 1;

View File

@ -70,6 +70,8 @@ ancestor() {
case $(uname -s) in
*MINGW*)
;;
*CYGWIN*)
;;
*)
test_set_prereq POSIX
;;

View File

@ -95,6 +95,27 @@ test_expect_success 'background auto gc does not run if gc.log is present and re
test_line_count = 1 packs
'
test_expect_success 'background auto gc respects lock for all operations' '
# make sure we run a background auto-gc
test_commit make-pack &&
git repack &&
test_config gc.autopacklimit 1 &&
test_config gc.autodetach true &&
# create a ref whose loose presence we can use to detect a pack-refs run
git update-ref refs/heads/should-be-loose HEAD &&
test_path_is_file .git/refs/heads/should-be-loose &&
# now fake a concurrent gc that holds the lock; we can use our
# shell pid so that it looks valid.
hostname=$(hostname || echo unknown) &&
printf "$$ %s" "$hostname" >.git/gc.pid &&
# our gc should exit zero without doing anything
run_and_wait_for_auto_gc &&
test_path_is_file .git/refs/heads/should-be-loose
'
# DO NOT leave a detached auto gc process running near the end of the
# test script: it can run long enough in the background to racily
# interfere with the cleanup in 'test_done'.

View File

@ -133,6 +133,13 @@ close TEMPFILE3;
unlink $tmpfile3;
chdir($abs_repo_dir);
# unquoting paths
is(Git::unquote_path('abc'), 'abc', 'unquote unquoted path');
is(Git::unquote_path('"abc def"'), 'abc def', 'unquote simple quoted path');
is(Git::unquote_path('"abc\"\\\\ \a\b\t\n\v\f\r\001\040"'),
"abc\"\\ \x07\x08\x09\x0a\x0b\x0c\x0d\x01 ",
'unquote escape sequences');
printf "1..%d\n", Test::More->builder->current_test;
my $is_passing = eval { Test::More->is_passing };

View File

@ -999,6 +999,7 @@ test_copy_bytes () {
my $s;
my $nread = sysread(STDIN, $s, $len);
die "cannot read: $!" unless defined($nread);
last unless $nread;
print $s;
$len -= $nread;
}

View File

@ -88,9 +88,7 @@ else
exit 1
fi
exit 0
################################################################
<<\DOC_END
This sample hook safeguards topic branches that have been
published from being rewound.
@ -167,3 +165,5 @@ To compute (2):
git rev-list master..topic
if this is empty, it is fully merged to "master".
DOC_END