From d306f3d3513c62342fec4e31457766f2473f9e9a Mon Sep 17 00:00:00 2001 From: Jeff King Date: Thu, 5 Feb 2015 03:14:19 -0500 Subject: [PATCH 01/16] decimal_width: avoid integer overflow The decimal_width function originally appeared in blame.c as "lineno_width", and was designed for calculating the print-width of small-ish integer values (line numbers in text files). In ec7ff5b, it was made into a reusable function, and in dc801e7, we started using it to align diffstats. Binary files in a diffstat show byte counts rather than line numbers, meaning they can be quite large (e.g., consider adding or removing a 2GB file). decimal_width is not up to the challenge for two reasons: 1. It takes the value as an "int", whereas large files may easily surpass this. The value may be truncated, in which case we will produce an incorrect value. 2. It counts "up" by repeatedly multiplying another integer by 10 until it surpasses the value. This can cause an infinite loop when the value is close to the largest representable integer. For example, consider using a 32-bit signed integer, and a value of 2,140,000,000 (just shy of 2^31-1). We will count up and eventually see that 1,000,000,000 is smaller than our value. The next step would be to multiply by 10 and see that 10,000,000,000 is too large, ending the loop. But we can't represent that value, and we have signed overflow. This is technically undefined behavior, but a common behavior is to lose the high bits, in which case our iterator will certainly be less than the number. So we'll keep multiplying, overflow again, and so on. This patch changes the argument to a uintmax_t (the same type we use to store the diffstat information for binary filese), and counts "down" by repeatedly dividing our value by 10. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- cache.h | 2 +- pager.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cache.h b/cache.h index 29ed24b802..db02a2de7f 100644 --- a/cache.h +++ b/cache.h @@ -1213,7 +1213,7 @@ extern const char *pager_program; extern int pager_in_use(void); extern int pager_use_color; extern int term_columns(void); -extern int decimal_width(int); +extern int decimal_width(uintmax_t); extern int check_pager_config(const char *cmd); extern const char *editor_program; diff --git a/pager.c b/pager.c index fa19765eb9..314210351b 100644 --- a/pager.c +++ b/pager.c @@ -139,12 +139,12 @@ int term_columns(void) /* * How many columns do we need to show this number in decimal? */ -int decimal_width(int number) +int decimal_width(uintmax_t number) { - int i, width; + int width; - for (width = 1, i = 10; i <= number; width++) - i *= 10; + for (width = 1; number >= 10; width++) + number /= 10; return width; } -- 2.11.4.GIT From 1d0655c15ebf7dfb460466d058daab790ed285b2 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Thu, 5 Feb 2015 16:00:24 -0500 Subject: [PATCH 02/16] config_buf_ungetc: warn when pushing back a random character Our config code simulates a stdio stream around a buffer, but our fake ungetc() does not behave quite like the real one. In particular, we only rewind the position by one character, but do _not_ actually put the character from the caller into position. It turns out that this does not matter, because we only ever push back the character we just read. In other words, such an assignment would be a noop. But because the function is called ungetc, and because it takes a character parameter, it is a mistake waiting to happen. Actually assigning the character into the buffer would be ideal, but our pointer is actually a "const" copy of the buffer. We do not know who the real owner of the buffer is in this code, and would not want to munge their contents. Instead, we can simply add an assertion that matches what the current caller does, and will let us know if new callers are added that violate the contract. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- config.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/config.c b/config.c index 5eca17b242..788970c6bc 100644 --- a/config.c +++ b/config.c @@ -63,8 +63,12 @@ static int config_buf_fgetc(struct config_source *conf) static int config_buf_ungetc(int c, struct config_source *conf) { - if (conf->u.buf.pos > 0) - return conf->u.buf.buf[--conf->u.buf.pos]; + if (conf->u.buf.pos > 0) { + conf->u.buf.pos--; + if (conf->u.buf.buf[conf->u.buf.pos] != c) + die("BUG: config_buf can only ungetc the same character"); + return c; + } return EOF; } -- 2.11.4.GIT From 9874fca7122563e28d699a911404fc49d2a24f1c Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 5 Feb 2015 13:23:56 -0800 Subject: [PATCH 03/16] Git 2.3 Signed-off-by: Junio C Hamano --- Documentation/RelNotes/2.3.0.txt | 6 ++++++ Documentation/git.txt | 5 +++++ GIT-VERSION-GEN | 2 +- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Documentation/RelNotes/2.3.0.txt b/Documentation/RelNotes/2.3.0.txt index 11dc73c383..e3c639c840 100644 --- a/Documentation/RelNotes/2.3.0.txt +++ b/Documentation/RelNotes/2.3.0.txt @@ -1,6 +1,12 @@ Git v2.3 Release Notes ====================== +This one ended up to be a release with lots of small corrections and +improvements without big uncomfortably exciting features. The recent +security fix that went to 2.2.1 and older maintenance tracks is also +contained in this update. + + Updates since v2.2 ------------------ diff --git a/Documentation/git.txt b/Documentation/git.txt index 9d33431427..eadbd05356 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -43,6 +43,11 @@ unreleased) version of Git, that is available from the 'master' branch of the `git.git` repository. Documentation for older releases are available here: +* link:v2.3.0/git.html[documentation for release 2.3] + +* release notes for + link:RelNotes/2.3.0.txt[2.3]. + * link:v2.2.2/git.html[documentation for release 2.2.2] * release notes for diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index 068eae29d6..780064ad71 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v2.3.0-rc2 +DEF_VER=v2.3.0 LF=' ' -- 2.11.4.GIT From 88c03eb5775546a2cae0d8cc9025ef7969b23485 Mon Sep 17 00:00:00 2001 From: "Kyle J. McKay" Date: Fri, 6 Feb 2015 01:35:31 -0800 Subject: [PATCH 04/16] git-compat-util: do not step on MAC_OS_X_VERSION_MIN_REQUIRED MAC_OS_X_VERSION_MIN_REQUIRED may be defined by the builder to a specific version in order to produce compatible binaries for a particular system. Blindly defining it to MAC_OS_X_VERSION_10_6 is bad. Additionally MAC_OS_X_VERSION_10_6 will not be defined on older systems and should AvailabilityMacros.h be included on such as system an error will result. However, using the explicit value of 1060 (which is what MAC_OS_X_VERSION_10_6 is defined to) does not solve the problem. The changes that introduced stepping on MAC_OS_X_VERSION_MIN were made in b195aa00 (git-compat-util: suppress unavoidable Apple-specific deprecation warnings) to avoid deprecation warnings. Instead of blindly setting MAC_OS_X_VERSION_MIN to 1060 change the definition of DEPRECATED_ATTRIBUTE to empty to avoid the warnings. This preserves any MAC_OS_X_VERSION_MIN_REQUIRED setting while avoiding the warnings as intended by b195aa00. Signed-off-by: Kyle J. McKay Signed-off-by: Junio C Hamano --- git-compat-util.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/git-compat-util.h b/git-compat-util.h index 433b8f2a1d..46563326f0 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -211,12 +211,15 @@ extern char *gitbasename(char *); #endif #ifndef NO_OPENSSL +#ifdef __APPLE__ #define __AVAILABILITY_MACROS_USES_AVAILABILITY 0 -#define MAC_OS_X_VERSION_MIN_REQUIRED MAC_OS_X_VERSION_10_6 +#include +#undef DEPRECATED_ATTRIBUTE +#define DEPRECATED_ATTRIBUTE +#undef __AVAILABILITY_MACROS_USES_AVAILABILITY +#endif #include #include -#undef MAC_OS_X_VERSION_MIN_REQUIRED -#undef __AVAILABILITY_MACROS_USES_AVAILABILITY #endif /* On most systems would have given us this, but -- 2.11.4.GIT From e6f875e052bb327d43d86b4e8335ebd4746d3e2a Mon Sep 17 00:00:00 2001 From: Jeff King Date: Sun, 8 Feb 2015 20:13:22 -0500 Subject: [PATCH 05/16] for_each_loose_file_in_objdir: take an optional strbuf path We feed a root "objdir" path to this iterator function, which then copies the result into a strbuf, so that it can repeatedly append the object sub-directories to it. Let's make it easy for callers to just pass us a strbuf in the first place. We leave the original interface as a convenience for callers who want to just pass a const string like the result of get_object_directory(). Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- cache.h | 9 +++++++++ sha1_file.c | 31 +++++++++++++++++++++---------- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/cache.h b/cache.h index 51ee856acc..4743f7ed9f 100644 --- a/cache.h +++ b/cache.h @@ -1256,6 +1256,10 @@ extern int unpack_object_header(struct packed_git *, struct pack_window **, off_ * * Any callback that is NULL will be ignored. Callbacks returning non-zero * will end the iteration. + * + * In the "buf" variant, "path" is a strbuf which will also be used as a + * scratch buffer, but restored to its original contents before + * the function returns. */ typedef int each_loose_object_fn(const unsigned char *sha1, const char *path, @@ -1271,6 +1275,11 @@ int for_each_loose_file_in_objdir(const char *path, each_loose_cruft_fn cruft_cb, each_loose_subdir_fn subdir_cb, void *data); +int for_each_loose_file_in_objdir_buf(struct strbuf *path, + each_loose_object_fn obj_cb, + each_loose_cruft_fn cruft_cb, + each_loose_subdir_fn subdir_cb, + void *data); /* * Iterate over loose and packed objects in both the local diff --git a/sha1_file.c b/sha1_file.c index c63264198e..725de7f9cf 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -3358,31 +3358,42 @@ static int for_each_file_in_obj_subdir(int subdir_nr, return r; } -int for_each_loose_file_in_objdir(const char *path, +int for_each_loose_file_in_objdir_buf(struct strbuf *path, each_loose_object_fn obj_cb, each_loose_cruft_fn cruft_cb, each_loose_subdir_fn subdir_cb, void *data) { - struct strbuf buf = STRBUF_INIT; - size_t baselen; + size_t baselen = path->len; int r = 0; int i; - strbuf_addstr(&buf, path); - strbuf_addch(&buf, '/'); - baselen = buf.len; - for (i = 0; i < 256; i++) { - strbuf_addf(&buf, "%02x", i); - r = for_each_file_in_obj_subdir(i, &buf, obj_cb, cruft_cb, + strbuf_addf(path, "/%02x", i); + r = for_each_file_in_obj_subdir(i, path, obj_cb, cruft_cb, subdir_cb, data); - strbuf_setlen(&buf, baselen); + strbuf_setlen(path, baselen); if (r) break; } + return r; +} + +int for_each_loose_file_in_objdir(const char *path, + each_loose_object_fn obj_cb, + each_loose_cruft_fn cruft_cb, + each_loose_subdir_fn subdir_cb, + void *data) +{ + struct strbuf buf = STRBUF_INIT; + int r; + + strbuf_addstr(&buf, path); + r = for_each_loose_file_in_objdir_buf(&buf, obj_cb, cruft_cb, + subdir_cb, data); strbuf_release(&buf); + return r; } -- 2.11.4.GIT From b0a4264277b7968741580093e7ea1e366943d297 Mon Sep 17 00:00:00 2001 From: Jonathon Mah Date: Sun, 8 Feb 2015 20:15:39 -0500 Subject: [PATCH 06/16] sha1_file: fix iterating loose alternate objects The string in 'base' contains a path suffix to a specific object; when its value is used, the suffix must either be filled (as in stat_sha1_file, open_sha1_file, check_and_freshen_nonlocal) or cleared (as in prepare_packed_git) to avoid junk at the end. 660c889e (sha1_file: add for_each iterators for loose and packed objects, 2014-10-15) introduced loose_from_alt_odb(), but this did neither and treated 'base' as a complete path to the "base" object directory, instead of a pointer to the "base" of the full path string. The trailing path after 'base' is still initialized to NUL, hiding the bug in some common cases. Additionally the descendent for_each_file_in_obj_subdir() function swallows ENOENT, so an error only shows if the alternate's path was last filled with a valid object (where statting /path/to/existing/00/0bjectfile/00 fails). Signed-off-by: Jonathon Mah Helped-by: Kyle J. McKay Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- sha1_file.c | 13 ++++++++++--- t/t5304-prune.sh | 8 ++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/sha1_file.c b/sha1_file.c index 725de7f9cf..a41cc4f65f 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -3406,9 +3406,16 @@ static int loose_from_alt_odb(struct alternate_object_database *alt, void *vdata) { struct loose_alt_odb_data *data = vdata; - return for_each_loose_file_in_objdir(alt->base, - data->cb, NULL, NULL, - data->data); + struct strbuf buf = STRBUF_INIT; + int r; + + /* copy base not including trailing '/' */ + strbuf_add(&buf, alt->base, alt->name - alt->base - 1); + r = for_each_loose_file_in_objdir_buf(&buf, + data->cb, NULL, NULL, + data->data); + strbuf_release(&buf); + return r; } int for_each_loose_object(each_loose_object_fn cb, void *data) diff --git a/t/t5304-prune.sh b/t/t5304-prune.sh index e32e46dee1..0794d33dad 100755 --- a/t/t5304-prune.sh +++ b/t/t5304-prune.sh @@ -253,4 +253,12 @@ test_expect_success 'prune .git/shallow' ' test_path_is_missing .git/shallow ' +test_expect_success 'prune: handle alternate object database' ' + test_create_repo A && + git -C A commit --allow-empty -m "initial commit" && + git clone --shared A B && + git -C B commit --allow-empty -m "next commit" && + git -C B prune +' + test_done -- 2.11.4.GIT From e60059276b26db5760e36aa85cf1091f662430fb Mon Sep 17 00:00:00 2001 From: Eric Sunshine Date: Mon, 9 Feb 2015 16:28:07 -0500 Subject: [PATCH 07/16] builtin/blame: destroy initialized commit_info only Since ea02ffa3 (mailmap: simplify map_user() interface, 2013-01-05), find_alignment() has been invoking commit_info_destroy() on an uninitialized auto 'struct commit_info' (when METAINFO_SHOWN is not set). commit_info_destroy() calls strbuf_release() for each 'commit_info' strbuf member, which randomly invokes free() on whatever random stack value happens to reside in strbuf.buf, thus leading to periodic crashes. Reported-by: Dilyan Palauzov Signed-off-by: Eric Sunshine Signed-off-by: Junio C Hamano --- builtin/blame.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/builtin/blame.c b/builtin/blame.c index 9047b6ef4c..078285d7d4 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -1843,7 +1843,6 @@ static void find_alignment(struct scoreboard *sb, int *option) for (e = sb->ent; e; e = e->next) { struct origin *suspect = e->suspect; - struct commit_info ci; int num; if (compute_auto_abbrev) @@ -1854,6 +1853,7 @@ static void find_alignment(struct scoreboard *sb, int *option) if (longest_file < num) longest_file = num; if (!(suspect->commit->object.flags & METAINFO_SHOWN)) { + struct commit_info ci; suspect->commit->object.flags |= METAINFO_SHOWN; get_commit_info(suspect->commit, &ci, 1); if (*option & OUTPUT_SHOW_EMAIL) @@ -1862,6 +1862,7 @@ static void find_alignment(struct scoreboard *sb, int *option) num = utf8_strwidth(ci.author.buf); if (longest_author < num) longest_author = num; + commit_info_destroy(&ci); } num = e->s_lno + e->num_lines; if (longest_src_lines < num) @@ -1871,8 +1872,6 @@ static void find_alignment(struct scoreboard *sb, int *option) longest_dst_lines = num; if (largest_score < ent_score(sb, e)) largest_score = ent_score(sb, e); - - commit_info_destroy(&ci); } max_orig_digits = decimal_width(longest_src_lines); max_digits = decimal_width(longest_dst_lines); -- 2.11.4.GIT From 204a8ffe67d2b789a34a14a06618a24756f7d9a9 Mon Sep 17 00:00:00 2001 From: Aleksander Boruch-Gruszecki Date: Sun, 8 Feb 2015 17:53:53 +0100 Subject: [PATCH 08/16] merge-file: correctly open files when in a subdir run_setup_gently() is called before merge-file. This may result in changing current working directory, which wasn't taken into account when opening a file for writing. Fix by prepending the passed prefix. Previous var is left so that error messages keep referring to the file from the user's working directory perspective. Signed-off-by: Aleksander Boruch-Gruszecki Signed-off-by: Junio C Hamano --- builtin/merge-file.c | 3 ++- t/t6023-merge-file.sh | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/builtin/merge-file.c b/builtin/merge-file.c index 844f84f40b..232b76857c 100644 --- a/builtin/merge-file.c +++ b/builtin/merge-file.c @@ -90,7 +90,8 @@ int cmd_merge_file(int argc, const char **argv, const char *prefix) if (ret >= 0) { const char *filename = argv[0]; - FILE *f = to_stdout ? stdout : fopen(filename, "wb"); + const char *fpath = prefix_filename(prefix, prefixlen, argv[0]); + FILE *f = to_stdout ? stdout : fopen(fpath, "wb"); if (!f) ret = error("Could not open %s for writing", filename); diff --git a/t/t6023-merge-file.sh b/t/t6023-merge-file.sh index 432f086c06..d0df869001 100755 --- a/t/t6023-merge-file.sh +++ b/t/t6023-merge-file.sh @@ -69,7 +69,8 @@ test_expect_success 'works in subdirectory' ' cp new1.txt dir/a.txt && cp orig.txt dir/o.txt && cp new2.txt dir/b.txt && - ( cd dir && git merge-file a.txt o.txt b.txt ) + ( cd dir && git merge-file a.txt o.txt b.txt ) && + test_path_is_missing a.txt ' cp new1.txt test.txt -- 2.11.4.GIT From 51334bb094e085728ffe2b603fa3fe41dd80c075 Mon Sep 17 00:00:00 2001 From: Luke Diamand Date: Sat, 17 Jan 2015 20:56:38 +0000 Subject: [PATCH 09/16] git-p4: support excluding paths on sync The clone subcommand has long had support for excluding subdirectories, but sync has not. This is a nuisance, since as soon as you do a sync, any changed files that were initially excluded start showing up. Move the "exclude" command-line option into the parent class; the actual behavior was already present there so it simply had to be exposed. Signed-off-by: Luke Diamand Reviewed-by: Pete Wyckoff Signed-off-by: Junio C Hamano --- Documentation/git-p4.txt | 6 ++-- git-p4.py | 20 ++++++------- t/t9817-git-p4-exclude.sh | 71 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 13 deletions(-) create mode 100755 t/t9817-git-p4-exclude.sh diff --git a/Documentation/git-p4.txt b/Documentation/git-p4.txt index 6ab5f9497a..a1664b9f68 100644 --- a/Documentation/git-p4.txt +++ b/Documentation/git-p4.txt @@ -241,6 +241,9 @@ Git repository: Use a client spec to find the list of interesting files in p4. See the "CLIENT SPEC" section below. +-/ :: + Exclude selected depot paths when cloning or syncing. + Clone options ~~~~~~~~~~~~~ These options can be used in an initial 'clone', along with the 'sync' @@ -254,9 +257,6 @@ options described above. --bare:: Perform a bare clone. See linkgit:git-clone[1]. --/ :: - Exclude selected depot paths when cloning. - Submit options ~~~~~~~~~~~~~~ These options can be used to modify 'git p4 submit' behavior. diff --git a/git-p4.py b/git-p4.py index ff132b2117..ad91057c5c 100755 --- a/git-p4.py +++ b/git-p4.py @@ -1915,7 +1915,10 @@ class P4Sync(Command, P4UserMap): optparse.make_option("--keep-path", dest="keepRepoPath", action='store_true', help="Keep entire BRANCH/DIR/SUBDIR prefix during import"), optparse.make_option("--use-client-spec", dest="useClientSpec", action='store_true', - help="Only sync files that are included in the Perforce Client Spec") + help="Only sync files that are included in the Perforce Client Spec"), + optparse.make_option("-/", dest="cloneExclude", + action="append", type="string", + help="exclude depot path"), ] self.description = """Imports from Perforce into a git repository.\n example: @@ -1950,6 +1953,12 @@ class P4Sync(Command, P4UserMap): if gitConfig("git-p4.syncFromOrigin") == "false": self.syncWithOrigin = False + # This is required for the "append" cloneExclude action + def ensure_value(self, attr, value): + if not hasattr(self, attr) or getattr(self, attr) is None: + setattr(self, attr, value) + return getattr(self, attr) + # Force a checkpoint in fast-import and wait for it to finish def checkpoint(self): self.gitStream.write("checkpoint\n\n") @@ -3101,9 +3110,6 @@ class P4Clone(P4Sync): optparse.make_option("--destination", dest="cloneDestination", action='store', default=None, help="where to leave result of the clone"), - optparse.make_option("-/", dest="cloneExclude", - action="append", type="string", - help="exclude depot path"), optparse.make_option("--bare", dest="cloneBare", action="store_true", default=False), ] @@ -3111,12 +3117,6 @@ class P4Clone(P4Sync): self.needsGit = False self.cloneBare = False - # This is required for the "append" cloneExclude action - def ensure_value(self, attr, value): - if not hasattr(self, attr) or getattr(self, attr) is None: - setattr(self, attr, value) - return getattr(self, attr) - def defaultDestination(self, args): ## TODO: use common prefix of args? depotPath = args[0] diff --git a/t/t9817-git-p4-exclude.sh b/t/t9817-git-p4-exclude.sh new file mode 100755 index 0000000000..aac568eadf --- /dev/null +++ b/t/t9817-git-p4-exclude.sh @@ -0,0 +1,71 @@ +#!/bin/sh + +test_description='git p4 tests for excluded paths during clone and sync' + +. ./lib-git-p4.sh + +test_expect_success 'start p4d' ' + start_p4d +' + +# Create a repo with the structure: +# +# //depot/wanted/foo +# //depot/discard/foo +# +# Check that we can exclude a subdirectory with both +# clone and sync operations. + +test_expect_success 'create exclude repo' ' + ( + cd "$cli" && + mkdir -p wanted discard && + echo wanted >wanted/foo && + echo discard >discard/foo && + p4 add wanted/foo discard/foo && + p4 submit -d "initial revision" + ) +' + +test_expect_success 'check the repo was created correctly' ' + test_when_finished cleanup_git && + git p4 clone --dest="$git" //depot/...@all && + ( + cd "$git" && + test_path_is_file wanted/foo && + test_path_is_file discard/foo + ) +' + +test_expect_success 'clone, excluding part of repo' ' + test_when_finished cleanup_git && + git p4 clone -//depot/discard/... --dest="$git" //depot/...@all && + ( + cd "$git" && + test_path_is_file wanted/foo && + test_path_is_missing discard/foo + ) +' + +test_expect_success 'clone, then sync with exclude' ' + test_when_finished cleanup_git && + git p4 clone -//depot/discard/... --dest="$git" //depot/...@all && + ( + cd "$cli" && + p4 edit wanted/foo discard/foo && + date >>wanted/foo && + date >>discard/foo && + p4 submit -d "updating" && + + cd "$git" && + git p4 sync -//depot/discard/... && + test_path_is_file wanted/foo && + test_path_is_missing discard/foo + ) +' + +test_expect_success 'kill p4d' ' + kill_p4d +' + +test_done -- 2.11.4.GIT From 18d0fec24027ac226dc2c4df2b955eef2a16462a Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 11 Feb 2015 13:54:03 -0800 Subject: [PATCH 10/16] Post 2.3 cycle (batch #1) Signed-off-by: Junio C Hamano --- RelNotes | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) rewrite RelNotes (100%) mode change 120000 => 100644 diff --git a/RelNotes b/RelNotes deleted file mode 120000 index 9257c74b5c..0000000000 --- a/RelNotes +++ /dev/null @@ -1 +0,0 @@ -Documentation/RelNotes/2.3.0.txt \ No newline at end of file diff --git a/RelNotes b/RelNotes new file mode 100644 index 0000000000..0fbbabb4f8 --- /dev/null +++ b/RelNotes @@ -0,0 +1,64 @@ +Git ???? Release Notes +====================== + +Updates since v2.3 +------------------ + +Ports + + +UI, Workflows & Features + + * The command usage info strings given by "git cmd -h" and in + documentation have been tweaked for consistency. + + * The "sync" subcommand of "git p4" now allows users to exclude + subdirectories like its "clone" subcommand does. + + * "git log --invert-grep --grep=WIP" will show only commits that do + not have the string "WIP" in their messages. + + * "git push" has been taught a "--atomic" option that makes push to + update more than one ref an "all-or-none" affair. + + * Extending the "push to deploy" added in 2.3, the behaviour of "git + push" when updating the branch that is checked out can now be + tweaked by push-to-checkout hook. + + +Performance, Internal Implementation, Development Support etc. + + * Implementation of N_() macro has been updated slightly to help us + detect mistakes. + + * Implementation of "reflog expire" has been restructured to fit the + reflogs better with the recently updated ref API. + + +Also contains various documentation updates and code clean-ups. + + +Fixes since v2.3 +---------------- + +Unless otherwise noted, all the fixes since v2.3 in the maintenance +track are contained in this release (see the maintenance releases' +notes for details). + + * "git blame HEAD -- missing" failed to correctly say "HEAD" when it + tried to say "No such path 'missing' in HEAD". + (merge a46442f jk/blame-commit-label later to maint). + + * "git rerere" (invoked internally from many mergy operations) did + not correctly signal errors when told to update the working tree + files and failed to do so for whatever reason. + (merge 89ea903 jn/rerere-fail-on-auto-update-failure later to maint). + + * Setting diff.submodule to 'log' made "git format-patch" produce + broken patches. + (merge 339de50 dk/format-patch-ignore-diff-submodule later to maint). + + * After attempting and failing a password-less authentication + (e.g. kerberos), libcURL refuses to fall back to password based + Basic authentication without a bit of help/encouragement. + (merge 4dbe664 bc/http-fallback-to-password-after-krb-fails later to maint). -- 2.11.4.GIT From 45917f0f994aee78dccf2a41000b48fc23db1a0b Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Thu, 12 Feb 2015 19:10:01 +0900 Subject: [PATCH 11/16] transport-helper: fix typo in error message when --signed is not supported Signed-off-by: Mike Hommey Signed-off-by: Junio C Hamano --- transport-helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/transport-helper.c b/transport-helper.c index 4b1a26143a..356165821f 100644 --- a/transport-helper.c +++ b/transport-helper.c @@ -865,7 +865,7 @@ static int push_refs_with_export(struct transport *transport, die("helper %s does not support dry-run", data->name); } else if (flags & TRANSPORT_PUSH_CERT) { if (set_helper_option(transport, TRANS_OPT_PUSH_CERT, "true") != 0) - die("helper %s does not support dry-run", data->name); + die("helper %s does not support --signed", data->name); } if (flags & TRANSPORT_PUSH_FORCE) { -- 2.11.4.GIT From 3188ab3af60df6ace996d3985e8f1ca1ed3cbda5 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 17 Feb 2015 10:22:17 -0800 Subject: [PATCH 12/16] Post 2.3 cycle (batch #2) Signed-off-by: Junio C Hamano --- RelNotes | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/RelNotes b/RelNotes index 0fbbabb4f8..5d5d2f8617 100644 --- a/RelNotes +++ b/RelNotes @@ -62,3 +62,51 @@ notes for details). (e.g. kerberos), libcURL refuses to fall back to password based Basic authentication without a bit of help/encouragement. (merge 4dbe664 bc/http-fallback-to-password-after-krb-fails later to maint). + + * The "git push" documentation made the "--repo=" option + easily misunderstood. + (merge 57b92a7 mg/push-repo-option-doc later to maint). + + * Code to read branch name from various files in .git/ directory + would have misbehaved if the code to write them left an empty file. + (merge 66ec904 jk/status-read-branch-name-fix later to maint). + + * A misspelled conditional that is always true has been fixed. + (merge 94ee8e2 jk/remote-curl-an-array-in-struct-cannot-be-null later to maint). + + * The documentation incorrectly said that C(opy) and R(ename) are the + only ones that can be followed by the score number in the output in + the --raw format. + (merge ac1c2d9 jc/diff-format-doc later to maint). + + * A broken pack .idx file in the receiving repository prevented the + dumb http transport from fetching a good copy of it from the other + side. + (merge 8b9c2dd jk/dumb-http-idx-fetch-fix later to maint). + + * The error message from "git commit", when a non-existing author + name was given as value to the "--author=" parameter, has been + reworded to avoid misunderstanding. + (merge 1044b1f mg/commit-author-no-match-malformed-message later to maint). + + * "git log --help" used to show rev-list options that are irrelevant + to the "log" command. + (merge 3cab02d jc/doc-log-rev-list-options later to maint). + + * "git apply --whitespace=fix" used to under-allocate the memory when + the fix resulted in a longer text than the original patch. + (merge 407a792 jc/apply-ws-fix-expands later to maint). + + * The interactive "show a list and let the user choose from it" + interface "add -i" used showed and prompted to the user even when + the candidate list was empty, against which the only "choice" the + user could have made was to choose nothing. + (merge a9c4641 ak/add-i-empty-candidates later to maint). + + * The insn sheet "git rebase -i" creates did not fully honor + core.abbrev settings. + (merge edb72d5 ks/rebase-i-abbrev later to maint). + + * "git fetch" over a remote-helper that cannot respond to "list" + command could not fetch from a symbolic reference e.g. HEAD. + (merge 33cae54 mh/deref-symref-over-helper-transport later to maint). -- 2.11.4.GIT From 98b16edfa0c9fd899a1be6f259cc597260898022 Mon Sep 17 00:00:00 2001 From: Michael J Gruber Date: Thu, 19 Feb 2015 10:29:19 +0100 Subject: [PATCH 13/16] tests: avoid z option to tar Some versions of tar don't have the z option for compression, and we don't really need it. So avoid it. --- t/t3513-revert-submodule.sh | 4 ++-- t/t6041-bisect-submodule.sh | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/t/t3513-revert-submodule.sh b/t/t3513-revert-submodule.sh index a1c4e0216f..db9378142a 100755 --- a/t/t3513-revert-submodule.sh +++ b/t/t3513-revert-submodule.sh @@ -14,11 +14,11 @@ test_description='revert can handle submodules' git_revert () { git status -su >expect && ls -1pR * >>expect && - tar czf "$TRASH_DIRECTORY/tmp.tgz" * && + tar cf "$TRASH_DIRECTORY/tmp.tar" * && git checkout "$1" && git revert HEAD && rm -rf * && - tar xzf "$TRASH_DIRECTORY/tmp.tgz" && + tar xf "$TRASH_DIRECTORY/tmp.tar" && git status -su >actual && ls -1pR * >>actual && test_cmp expect actual && diff --git a/t/t6041-bisect-submodule.sh b/t/t6041-bisect-submodule.sh index c6b7aa6977..62b8a2e7bb 100755 --- a/t/t6041-bisect-submodule.sh +++ b/t/t6041-bisect-submodule.sh @@ -8,7 +8,7 @@ test_description='bisect can handle submodules' git_bisect () { git status -su >expect && ls -1pR * >>expect && - tar czf "$TRASH_DIRECTORY/tmp.tgz" * && + tar cf "$TRASH_DIRECTORY/tmp.tar" * && GOOD=$(git rev-parse --verify HEAD) && git checkout "$1" && echo "foo" >bar && @@ -20,7 +20,7 @@ git_bisect () { git bisect start && git bisect good $GOOD && rm -rf * && - tar xzf "$TRASH_DIRECTORY/tmp.tgz" && + tar xf "$TRASH_DIRECTORY/tmp.tar" && git status -su >actual && ls -1pR * >>actual && test_cmp expect actual && -- 2.11.4.GIT From 27a5b7ef670431274c56b72fb13031df303a00dd Mon Sep 17 00:00:00 2001 From: Michael J Gruber Date: Thu, 19 Feb 2015 11:06:20 +0100 Subject: [PATCH 14/16] tests: use $TAR, not tar Some of our tests use $TAR (which defaults to "tar"), some tar. make all of them use $TAR consistently. --- t/t3513-revert-submodule.sh | 4 ++-- t/t6041-bisect-submodule.sh | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/t/t3513-revert-submodule.sh b/t/t3513-revert-submodule.sh index db9378142a..3141c5f06f 100755 --- a/t/t3513-revert-submodule.sh +++ b/t/t3513-revert-submodule.sh @@ -14,11 +14,11 @@ test_description='revert can handle submodules' git_revert () { git status -su >expect && ls -1pR * >>expect && - tar cf "$TRASH_DIRECTORY/tmp.tar" * && + "$TAR" cf "$TRASH_DIRECTORY/tmp.tar" * && git checkout "$1" && git revert HEAD && rm -rf * && - tar xf "$TRASH_DIRECTORY/tmp.tar" && + "$TAR" xf "$TRASH_DIRECTORY/tmp.tar" && git status -su >actual && ls -1pR * >>actual && test_cmp expect actual && diff --git a/t/t6041-bisect-submodule.sh b/t/t6041-bisect-submodule.sh index 62b8a2e7bb..a2a03d289f 100755 --- a/t/t6041-bisect-submodule.sh +++ b/t/t6041-bisect-submodule.sh @@ -8,7 +8,7 @@ test_description='bisect can handle submodules' git_bisect () { git status -su >expect && ls -1pR * >>expect && - tar cf "$TRASH_DIRECTORY/tmp.tar" * && + "$TAR" cf "$TRASH_DIRECTORY/tmp.tar" * && GOOD=$(git rev-parse --verify HEAD) && git checkout "$1" && echo "foo" >bar && @@ -20,7 +20,7 @@ git_bisect () { git bisect start && git bisect good $GOOD && rm -rf * && - tar xf "$TRASH_DIRECTORY/tmp.tar" && + "$TAR" xf "$TRASH_DIRECTORY/tmp.tar" && git status -su >actual && ls -1pR * >>actual && test_cmp expect actual && -- 2.11.4.GIT From 81e44fe4f65df037eb5b33fbabca2a629b14eac3 Mon Sep 17 00:00:00 2001 From: Michael J Gruber Date: Thu, 19 Feb 2015 11:22:53 +0100 Subject: [PATCH 15/16] tests: avoid cp -P Some cp implementations do not understand -P for preserving symlinks. Use tar instead. --- t/t7001-mv.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/t/t7001-mv.sh b/t/t7001-mv.sh index 69f11bd40d..9780196c0b 100755 --- a/t/t7001-mv.sh +++ b/t/t7001-mv.sh @@ -308,7 +308,8 @@ test_expect_success 'git mv moves a submodule with a .git directory and no .gitm ( cd sub && rm -f .git && - cp -R -P -p ../.git/modules/sub .git && + mkdir .git && + (cd ../.git/modules/sub && tar cf - .) | (cd .git && tar xf -) && GIT_WORK_TREE=. git config --unset core.worktree ) && mkdir mod && @@ -331,7 +332,8 @@ test_expect_success 'git mv moves a submodule with a .git directory and .gitmodu ( cd sub && rm -f .git && - cp -R -P -p ../.git/modules/sub .git && + mkdir .git && + (cd ../.git/modules/sub && tar cf - .) | (cd .git && tar xf -) && GIT_WORK_TREE=. git config --unset core.worktree ) && mkdir mod && -- 2.11.4.GIT From 1d5a2c75383ab0aadd264fd2adc341cc7bf3bf68 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Thu, 19 Feb 2015 07:54:33 -0500 Subject: [PATCH 16/16] Interested in helping open source friends on HP-UX? On Thu, Feb 19, 2015 at 12:20:02PM +0100, Michael J Gruber wrote: > OK, so we should use NO_ICONV on HP_UX then. > > >> Failing so many tests with NO_ICONV is certainly not ideal, but I'm not > >> sure we should care to protect so many tests with a prerequisite. > > > > How feasible is it to isolate those tests into separate test files that > > people that know to not use e.g. Asian can safely ignore them? > > We have the prerequisite mechanism for that, and most probably, the > tests are "isolated" already, in the sense that with NO_ICONV, only > trivial setup tests succeed for those test files but all "proper" tests > fail. But I'll check. Need a good test to set the prerequisite, though. I took a first pass at this. The results are below (and I am hoping one of you can use it as a base to build on, as I do not want to commit to doing the second half, as you will see :) ). It passes NO_ICONV through to the test suite, sets up a prerequisite, disables some test scripts which are purely about i18n (e.g., t3900-i18n-commit), and marks some of the scripts with one-off tests using the ICONV prereq. Note that it also has some code changes around reencode_string_len. These aren't strictly necessary, but they silence gcc warnings when compiled with NO_ICONV. In that case we do: #define reencode_string_len(a,b,c,d,e) NULL but "e" is an out-parameter. We don't promise it is valid if the function returns NULL (which it does here). I'm kind of surprised the compiler doesn't realize that: foo = reencode_string_len(...); if (foo) bar(); is dead code, since the first line becomes "foo = NULL". So that's optional. So, on to the tricky parts. Here are the failures that remain: 1. The script builds up a commit history through the script, and later tests depend on this for things like commit timestamps or the exact shape of history. t9350 is an example of this (it has one failing test which can be marked, but then other tests later fail in confusing ways). 2. The script creates commits with encoded commit messages, then uses those both for cases that care about the encoding, and those that do not. t4041 is an example here. I think it would be best to use vanilla commit mesages for the main body of tests, and then explicitly test the encoding-related features separately. I think t4205 and t6006 are in this boat, too. I also tested this on a system with a working "iconv". If we are building with NO_ICONV, I am tempted to say that there should be no need to run the "iconv" command-line program at all. But t6006, for example, does it a lot outside of any test_expect_*. Probably it should be: test_lazy_prereq ICONV ' test -z "$NO_ICONV" && utf8_o=$(printf "\303\263") && latin1_o=$(printf "\363") && test "$(echo $utf8_o | iconv -f UTF-8 -t ISO-8559-1)" = "$latin1_o" ' or something, and all of that setup should be wrapped in a "test_expect_success ICONV ...". Of course that is the easy part. The hard part is splitting the ICONV setup from the vanilla commit setup so that the other tests can run. --- Makefile | 1 + pretty.c | 2 +- strbuf.c | 2 +- t/t3900-i18n-commit.sh | 5 +++++ t/t3901-i18n-patch.sh | 5 +++++ t/t4201-shortlog.sh | 2 +- t/t4210-log-i18n.sh | 5 +++++ t/t5100-mailinfo.sh | 2 +- t/t5550-http-fetch-dumb.sh | 4 ++-- t/t7102-reset.sh | 4 ++-- t/t8005-blame-i18n.sh | 5 +++++ t/test-lib.sh | 1 + 12 files changed, 30 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index 44f1dd10ff..d1a2e6c731 100644 --- a/Makefile +++ b/Makefile @@ -2112,6 +2112,7 @@ endif ifdef GIT_TEST_CMP_USE_COPIED_CONTEXT @echo GIT_TEST_CMP_USE_COPIED_CONTEXT=YesPlease >>$@ endif + @echo NO_ICONV=\''$(subst ','\'',$(subst ','\'',$(NO_ICONV)))'\' >>$@ @echo NO_GETTEXT=\''$(subst ','\'',$(subst ','\'',$(NO_GETTEXT)))'\' >>$@ @echo GETTEXT_POISON=\''$(subst ','\'',$(subst ','\'',$(GETTEXT_POISON)))'\' >>$@ ifdef GIT_PERF_REPEAT_COUNT diff --git a/pretty.c b/pretty.c index 9d34d02db1..74fe5fbf2e 100644 --- a/pretty.c +++ b/pretty.c @@ -1497,7 +1497,7 @@ void format_commit_message(const struct commit *commit, } if (output_enc) { - int outsz; + int outsz = 0; char *out = reencode_string_len(sb->buf, sb->len, output_enc, utf8, &outsz); if (out) diff --git a/strbuf.c b/strbuf.c index 88cafd4a70..6d8ad4b5ba 100644 --- a/strbuf.c +++ b/strbuf.c @@ -94,7 +94,7 @@ void strbuf_ltrim(struct strbuf *sb) int strbuf_reencode(struct strbuf *sb, const char *from, const char *to) { char *out; - int len; + int len = 0; if (same_encoding(from, to)) return 0; diff --git a/t/t3900-i18n-commit.sh b/t/t3900-i18n-commit.sh index 4bf1dbe9c9..d522677b77 100755 --- a/t/t3900-i18n-commit.sh +++ b/t/t3900-i18n-commit.sh @@ -7,6 +7,11 @@ test_description='commit and log output encodings' . ./test-lib.sh +if ! test_have_prereq ICONV; then + skip_all='skipping i18n tests, iconv not available' + test_done +fi + compare_with () { git show -s $1 | sed -e '1,/^$/d' -e 's/^ //' >current && case "$3" in diff --git a/t/t3901-i18n-patch.sh b/t/t3901-i18n-patch.sh index a392f3d1d6..c4f9d062bd 100755 --- a/t/t3901-i18n-patch.sh +++ b/t/t3901-i18n-patch.sh @@ -7,6 +7,11 @@ test_description='i18n settings and format-patch | am pipe' . ./test-lib.sh +if ! test_have_prereq ICONV; then + skip_all='skipping i18n tests, iconv not available' + test_done +fi + check_encoding () { # Make sure characters are not corrupted cnt="$1" header="$2" i=1 j=0 bad=0 diff --git a/t/t4201-shortlog.sh b/t/t4201-shortlog.sh index 7600a3e3e8..6ac715011a 100755 --- a/t/t4201-shortlog.sh +++ b/t/t4201-shortlog.sh @@ -159,7 +159,7 @@ $DSCHO (2): EOF -test_expect_success !MINGW 'shortlog encoding' ' +test_expect_success !MINGW,ICONV 'shortlog encoding' ' git reset --hard "$commit" && git config --unset i18n.commitencoding && echo 2 > a1 && diff --git a/t/t4210-log-i18n.sh b/t/t4210-log-i18n.sh index e585fe6129..12b82f9aa2 100755 --- a/t/t4210-log-i18n.sh +++ b/t/t4210-log-i18n.sh @@ -3,6 +3,11 @@ test_description='test log with i18n features' . ./test-lib.sh +if ! test_have_prereq ICONV; then + skip_all='skipping i18n tests, iconv not available' + test_done +fi + # two forms of é utf8_e=$(printf '\303\251') latin1_e=$(printf '\351') diff --git a/t/t5100-mailinfo.sh b/t/t5100-mailinfo.sh index 60df10f46a..d904696ebc 100755 --- a/t/t5100-mailinfo.sh +++ b/t/t5100-mailinfo.sh @@ -53,7 +53,7 @@ test_expect_success 'split box with rfc2047 samples' \ for mail in `echo rfc2047/00*` do - test_expect_success "mailinfo $mail" ' + test_expect_success ICONV "mailinfo $mail" ' git mailinfo -u $mail-msg $mail-patch <$mail >$mail-info && echo msg && test_cmp "$TEST_DIRECTORY"/t5100/empty $mail-msg && diff --git a/t/t5550-http-fetch-dumb.sh b/t/t5550-http-fetch-dumb.sh index 2731ad4cea..1aa212b492 100755 --- a/t/t5550-http-fetch-dumb.sh +++ b/t/t5550-http-fetch-dumb.sh @@ -204,12 +204,12 @@ test_expect_success 'git client shows text/plain with a charset' ' grep "this is the error message" stderr ' -test_expect_success 'http error messages are reencoded' ' +test_expect_success ICONV 'http error messages are reencoded' ' test_must_fail git clone "$HTTPD_URL/error/utf16" 2>stderr && grep "this is the error message" stderr ' -test_expect_success 'reencoding is robust to whitespace oddities' ' +test_expect_success ICONV 'reencoding is robust to whitespace oddities' ' test_must_fail git clone "$HTTPD_URL/error/odd-spacing" 2>stderr && grep "this is the error message" stderr ' diff --git a/t/t7102-reset.sh b/t/t7102-reset.sh index 98bcfe21aa..a7168d399c 100755 --- a/t/t7102-reset.sh +++ b/t/t7102-reset.sh @@ -62,14 +62,14 @@ check_changes () { done | test_cmp .cat_expect - } -test_expect_success 'reset --hard message' ' +test_expect_success ICONV 'reset --hard message' ' hex=$(git log -1 --format="%h") && git reset --hard > .actual && echo HEAD is now at $hex $(commit_msg) > .expected && test_cmp .expected .actual ' -test_expect_success 'reset --hard message (ISO8859-1 logoutputencoding)' ' +test_expect_success ICONV 'reset --hard message (ISO8859-1 logoutputencoding)' ' hex=$(git log -1 --format="%h") && git -c "i18n.logOutputEncoding=$test_encoding" reset --hard > .actual && echo HEAD is now at $hex $(commit_msg $test_encoding) > .expected && diff --git a/t/t8005-blame-i18n.sh b/t/t8005-blame-i18n.sh index 847d098c09..8c3ab28104 100755 --- a/t/t8005-blame-i18n.sh +++ b/t/t8005-blame-i18n.sh @@ -3,6 +3,11 @@ test_description='git blame encoding conversion' . ./test-lib.sh +if ! test_have_prereq ICONV; then + skip_all='skipping i18n tests, iconv not available' + test_done +fi + . "$TEST_DIRECTORY"/t8005/utf8.txt . "$TEST_DIRECTORY"/t8005/euc-japan.txt . "$TEST_DIRECTORY"/t8005/sjis.txt diff --git a/t/test-lib.sh b/t/test-lib.sh index bb1402de94..cef41a8e55 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -940,6 +940,7 @@ test -z "$NO_PERL" && test_set_prereq PERL test -z "$NO_PYTHON" && test_set_prereq PYTHON test -n "$USE_LIBPCRE" && test_set_prereq LIBPCRE test -z "$NO_GETTEXT" && test_set_prereq GETTEXT +test -z "$NO_ICONV" && test_set_prereq ICONV # Can we rely on git's output in the C locale? if test -n "$GETTEXT_POISON" -- 2.11.4.GIT