diff options
30 files changed, 427 insertions, 74 deletions
diff --git a/Documentation/RelNotes/1.7.11.7.txt b/Documentation/RelNotes/1.7.11.7.txt index e7e79d999b..e743a2a8e4 100644 --- a/Documentation/RelNotes/1.7.11.7.txt +++ b/Documentation/RelNotes/1.7.11.7.txt @@ -25,7 +25,7 @@ Fixes since v1.7.11.6 references" nor "Reload" did not update what is shown as the contents of it, when the user overwrote the tag with "git tag -f". - * "git for-each-ref" did not currectly support more than one --sort + * "git for-each-ref" did not correctly support more than one --sort option. * "git log .." errored out saying it is both rev range and a path diff --git a/Documentation/RelNotes/2.17.0.txt b/Documentation/RelNotes/2.17.0.txt index d6db0e19cf..c2cf891f71 100644 --- a/Documentation/RelNotes/2.17.0.txt +++ b/Documentation/RelNotes/2.17.0.txt @@ -342,7 +342,7 @@ Fixes since v2.16 validate the data and connected-ness of objects in the received pack; the code to perform this check has been taught about the narrow clone's convention that missing objects that are reachable - from objects in a pack that came from a promissor remote is OK. + from objects in a pack that came from a promisor remote is OK. * There was an unused file-scope static variable left in http.c when building for versions of libCURL that is older than 7.19.4, which diff --git a/Documentation/RelNotes/2.18.0.txt b/Documentation/RelNotes/2.18.0.txt index 7c59bd92fb..3ea280cf68 100644 --- a/Documentation/RelNotes/2.18.0.txt +++ b/Documentation/RelNotes/2.18.0.txt @@ -104,7 +104,7 @@ UI, Workflows & Features * The command line completion mechanism (in contrib/) learned to load custom completion file for "git $command" where $command is a custom "git-$command" that the end user has on the $PATH when using - newer version of bash. + newer version of bash-completion. * "git send-email" can sometimes offer confirmation dialog "Send this email?" with choices 'Yes', 'No', 'Quit', and 'All'. A new action @@ -324,7 +324,7 @@ Fixes since v2.17 after giving an error message. (merge 3bb0923f06 ps/contains-id-error-message later to maint). - * "diff-highlight" filter (in contrib/) learned to undertand "git log + * "diff-highlight" filter (in contrib/) learned to understand "git log --graph" output better. (merge 4551fbba14 jk/diff-highlight-graph-fix later to maint). @@ -523,6 +523,22 @@ Fixes since v2.17 packfile available to itself. (merge 3737746120 jk/index-pack-maint later to maint). + * Make zlib inflate codepath more robust against versions of zlib + that clobber unused portion of outbuf. + (merge b611396e97 jl/zlib-restore-nul-termination later to maint). + + * Fix old merge glitch in Documentation during v2.13-rc0 era. + (merge 28cb06020b mw/doc-merge-enumfix later to maint). + + * The code to read compressed bitmap was not careful to avoid reading + past the end of the file, which has been corrected. + (merge 1140bf01ec jk/ewah-bounds-check later to maint). + + * "make NO_ICONV=NoThanks" did not override NEEDS_LIBICONV + (i.e. linkage of -lintl, -liconv, etc. that are platform-specific + tweaks), which has been corrected. + (merge fdb1fbbc7d es/make-no-iconv later to maint). + * Other minor doc, test and build updates and code cleanups. (merge 248f66ed8e nd/trace-with-env later to maint). (merge 14ced5562c ys/bisect-object-id-missing-conversion-fix later to maint). @@ -559,3 +575,9 @@ Fixes since v2.17 (merge f156a0934a rd/p4-doc-markup-env later to maint). (merge 2a00502b14 tg/doc-sec-list later to maint). (merge 47cc91310a jk/submodule-fsck-loose-fixup later to maint). + (merge efde7b725c rd/comment-typofix-in-sha1-file later to maint). + (merge 7eedad15df rd/diff-options-typofix later to maint). + (merge 58ebd936cc km/doc-workflows-typofix later to maint). + (merge 30aa96cdf8 rd/doc-remote-tracking-with-hyphen later to maint). + (merge cf317877e3 ks/branch-set-upstream later to maint). + (merge 8de19d6be8 sg/t7406-chain-fix later to maint). diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt index f466600972..41064909ee 100644 --- a/Documentation/diff-options.txt +++ b/Documentation/diff-options.txt @@ -64,7 +64,7 @@ ifndef::git-format-patch[] endif::git-format-patch[] --indent-heuristic:: - Enable the heuristic that shift diff hunk boundaries to make patches + Enable the heuristic that shifts diff hunk boundaries to make patches easier to read. This is the default. --no-indent-heuristic:: @@ -106,7 +106,7 @@ diff" algorithm internally. low-occurrence common elements". -- + -For instance, if you configured diff.algorithm variable to a +For instance, if you configured the `diff.algorithm` variable to a non-default value and want to use the default one, then you have to use `--diff-algorithm=default` option. @@ -133,7 +133,7 @@ These parameters can also be set individually with `--stat-width=<width>`, as file creations or deletions ("new" or "gone", optionally "+l" if it's a symlink) and mode changes ("+x" or "-x" for adding or removing executable bit respectively) in diffstat. The - information is put betwen the filename part and the graph + information is put between the filename part and the graph part. Implies `--stat`. --numstat:: @@ -350,7 +350,7 @@ ifndef::git-format-patch[] Warn if changes introduce conflict markers or whitespace errors. What are considered whitespace errors is controlled by `core.whitespace` configuration. By default, trailing whitespaces (including - lines that solely consist of whitespaces) and a space character + lines that consist solely of whitespaces) and a space character that is immediately followed by a tab character inside the initial indent of the line are considered whitespace errors. Exits with non-zero status if problems are found. Not compatible @@ -364,7 +364,7 @@ ifndef::git-format-patch[] this option is not given, and the configuration variable `diff.wsErrorHighlight` is not set, only whitespace errors in `new` lines are highlighted. The whitespace errors are colored - whith `color.diff.whitespace`. + with `color.diff.whitespace`. endif::git-format-patch[] diff --git a/Documentation/git-merge.txt b/Documentation/git-merge.txt index d5dfd8430f..6a5c00e2c2 100644 --- a/Documentation/git-merge.txt +++ b/Documentation/git-merge.txt @@ -57,7 +57,7 @@ reconstruct the original (pre-merge) changes. Therefore: discouraged: while possible, it may leave you in a state that is hard to back out of in the case of a conflict. -The fourth syntax ("`git merge --continue`") can only be run after the +The third syntax ("`git merge --continue`") can only be run after the merge has resulted in conflicts. OPTIONS diff --git a/Documentation/git-p4.txt b/Documentation/git-p4.txt index b9fecebc0c..f0de3b891b 100644 --- a/Documentation/git-p4.txt +++ b/Documentation/git-p4.txt @@ -149,6 +149,12 @@ To specify a branch other than the current one, use: $ git p4 submit topicbranch ------------ +To specify a single commit or a range of commits, use: +------------ +$ git p4 submit --commit <sha1> +$ git p4 submit --commit <sha1..sha1> +------------ + The upstream reference is generally 'refs/remotes/p4/master', but can be overridden using the `--origin=` command-line option. @@ -355,6 +361,19 @@ These options can be used to modify 'git p4 submit' behavior. p4/master. See the "Sync options" section above for more information. +--commit <sha1>|<sha1..sha1>:: + Submit only the specified commit or range of commits, instead of the full + list of changes that are in the current Git branch. + +--disable-rebase:: + Disable the automatic rebase after all commits have been successfully + submitted. Can also be set with git-p4.disableRebase. + +--disable-p4sync:: + Disable the automatic sync of p4/master from Perforce after commits have + been submitted. Implies --disable-rebase. Can also be set with + git-p4.disableP4Sync. Sync with origin/master still goes ahead if possible. + Rebase options ~~~~~~~~~~~~~~ These options can be used to modify 'git p4 rebase' behavior. @@ -676,6 +695,12 @@ git-p4.conflict:: Specify submit behavior when a conflict with p4 is found, as per --conflict. The default behavior is 'ask'. +git-p4.disableRebase:: + Do not rebase the tree against p4/master following a submit. + +git-p4.disableP4Sync:: + Do not sync p4/master with Perforce following a submit. Implies git-p4.disableRebase. + IMPLEMENTATION DETAILS ---------------------- * Changesets from p4 are imported using Git fast-import. diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt index 4a5cc38a6f..ef9d9d28a9 100644 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@ -42,8 +42,8 @@ have to use '../foo.git' instead of './foo.git' - as one might expect when following the rules for relative URLs - because the evaluation of relative URLs in Git is identical to that of relative directories). + -The default remote is the remote of the remote tracking branch -of the current branch. If no such remote tracking branch exists or +The default remote is the remote of the remote-tracking branch +of the current branch. If no such remote-tracking branch exists or the HEAD is detached, "origin" is assumed to be the default remote. If the superproject doesn't have a default remote configured the superproject is its own authoritative upstream and the current diff --git a/Documentation/gitworkflows.txt b/Documentation/gitworkflows.txt index 926e044d09..ca11c7bdaf 100644 --- a/Documentation/gitworkflows.txt +++ b/Documentation/gitworkflows.txt @@ -107,7 +107,7 @@ the unstable branch into the stable one. Hence the following: .Merge upwards [caption="Rule: "] ===================================== -Always commit your fixes to the oldest supported branch that require +Always commit your fixes to the oldest supported branch that requires them. Then (periodically) merge the integration branches upwards into each other. ===================================== @@ -1351,17 +1351,19 @@ ifdef APPLE_COMMON_CRYPTO LIB_4_CRYPTO += -framework Security -framework CoreFoundation endif endif -ifdef NEEDS_LIBICONV - ifdef ICONVDIR - BASIC_CFLAGS += -I$(ICONVDIR)/include - ICONV_LINK = -L$(ICONVDIR)/$(lib) $(CC_LD_DYNPATH)$(ICONVDIR)/$(lib) - else - ICONV_LINK = - endif - ifdef NEEDS_LIBINTL_BEFORE_LIBICONV - ICONV_LINK += -lintl +ifndef NO_ICONV + ifdef NEEDS_LIBICONV + ifdef ICONVDIR + BASIC_CFLAGS += -I$(ICONVDIR)/include + ICONV_LINK = -L$(ICONVDIR)/$(lib) $(CC_LD_DYNPATH)$(ICONVDIR)/$(lib) + else + ICONV_LINK = + endif + ifdef NEEDS_LIBINTL_BEFORE_LIBICONV + ICONV_LINK += -lintl + endif + EXTLIBS += $(ICONV_LINK) -liconv endif - EXTLIBS += $(ICONV_LINK) -liconv endif ifdef NEEDS_LIBGEN EXTLIBS += -lgen diff --git a/builtin/blame.c b/builtin/blame.c index 4202584f97..3295718841 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -411,6 +411,7 @@ static void parse_color_fields(const char *s) die (_("must end with a color")); colorfield[colorfield_nr].hop = TIME_MAX; + string_list_clear(&l, 0); } static void setup_default_color_by_age(void) diff --git a/builtin/branch.c b/builtin/branch.c index d53f6e2ad4..5217ba3bde 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -701,7 +701,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix) * If no sorting parameter is given then we default to sorting * by 'refname'. This would give us an alphabetically sorted * array with the 'HEAD' ref at the beginning followed by - * local branches 'refs/heads/...' and finally remote-tacking + * local branches 'refs/heads/...' and finally remote-tracking * branches 'refs/remotes/...'. */ if (!sorting) diff --git a/builtin/pull.c b/builtin/pull.c index 1f2ecf3a88..49cc3beb4c 100644 --- a/builtin/pull.c +++ b/builtin/pull.c @@ -673,7 +673,7 @@ static const char *get_upstream_branch(const char *remote) } /** - * Derives the remote tracking branch from the remote and refspec. + * Derives the remote-tracking branch from the remote and refspec. * * FIXME: The current implementation assumes the default mapping of * refs/heads/<branch_name> to refs/remotes/<remote_name>/<branch_name>. @@ -711,7 +711,7 @@ static const char *get_tracking_branch(const char *remote, const char *refspec) /** * Given the repo and refspecs, sets fork_point to the point at which the - * current branch forked from its remote tracking branch. Returns 0 on success, + * current branch forked from its remote-tracking branch. Returns 0 on success, * -1 on failure. */ static int get_rebase_fork_point(struct object_id *fork_point, const char *repo, diff --git a/contrib/credential/netrc/git-credential-netrc b/contrib/credential/netrc/git-credential-netrc index 0b9a94102e..ebfc123ec6 100755 --- a/contrib/credential/netrc/git-credential-netrc +++ b/contrib/credential/netrc/git-credential-netrc @@ -2,7 +2,6 @@ use strict; use warnings; -use autodie; use Getopt::Long; use File::Basename; @@ -2853,7 +2853,8 @@ struct untracked_cache *read_untracked_extension(const void *data, unsigned long struct read_data rd; const unsigned char *next = data, *end = (const unsigned char *)data + sz; const char *ident; - int ident_len, len; + int ident_len; + ssize_t len; const char *exclude_per_dir; if (sz <= 1 || end[-1] != '\0') diff --git a/ewah/ewah_io.c b/ewah/ewah_io.c index bed1994551..33c08c40f8 100644 --- a/ewah/ewah_io.c +++ b/ewah/ewah_io.c @@ -122,16 +122,23 @@ int ewah_serialize_strbuf(struct ewah_bitmap *self, struct strbuf *sb) return ewah_serialize_to(self, write_strbuf, sb); } -int ewah_read_mmap(struct ewah_bitmap *self, const void *map, size_t len) +ssize_t ewah_read_mmap(struct ewah_bitmap *self, const void *map, size_t len) { const uint8_t *ptr = map; + size_t data_len; size_t i; + if (len < sizeof(uint32_t)) + return error("corrupt ewah bitmap: eof before bit size"); self->bit_size = get_be32(ptr); ptr += sizeof(uint32_t); + len -= sizeof(uint32_t); + if (len < sizeof(uint32_t)) + return error("corrupt ewah bitmap: eof before length"); self->buffer_size = self->alloc_size = get_be32(ptr); ptr += sizeof(uint32_t); + len -= sizeof(uint32_t); REALLOC_ARRAY(self->buffer, self->alloc_size); @@ -141,15 +148,25 @@ int ewah_read_mmap(struct ewah_bitmap *self, const void *map, size_t len) * the endianness conversion in a separate pass to ensure * we're loading 8-byte aligned words. */ - memcpy(self->buffer, ptr, self->buffer_size * sizeof(eword_t)); - ptr += self->buffer_size * sizeof(eword_t); + data_len = st_mult(self->buffer_size, sizeof(eword_t)); + if (len < data_len) + return error("corrupt ewah bitmap: eof in data " + "(%"PRIuMAX" bytes short)", + (uintmax_t)(data_len - len)); + memcpy(self->buffer, ptr, data_len); + ptr += data_len; + len -= data_len; for (i = 0; i < self->buffer_size; ++i) self->buffer[i] = ntohll(self->buffer[i]); + if (len < sizeof(uint32_t)) + return error("corrupt ewah bitmap: eof before rlw"); self->rlw = self->buffer + get_be32(ptr); + ptr += sizeof(uint32_t); + len -= sizeof(uint32_t); - return (3 * 4) + (self->buffer_size * 8); + return ptr - (const uint8_t *)map; } int ewah_deserialize(struct ewah_bitmap *self, int fd) diff --git a/ewah/ewok.h b/ewah/ewok.h index dc43d05b64..357fd93c84 100644 --- a/ewah/ewok.h +++ b/ewah/ewok.h @@ -91,7 +91,7 @@ int ewah_serialize_native(struct ewah_bitmap *self, int fd); int ewah_serialize_strbuf(struct ewah_bitmap *self, struct strbuf *); int ewah_deserialize(struct ewah_bitmap *self, int fd); -int ewah_read_mmap(struct ewah_bitmap *self, const void *map, size_t len); +ssize_t ewah_read_mmap(struct ewah_bitmap *self, const void *map, size_t len); uint32_t ewah_checksum(struct ewah_bitmap *self); @@ -47,8 +47,10 @@ verbose = False # Only labels/tags matching this will be imported/exported defaultLabelRegexp = r'[a-zA-Z0-9_\-.]+$' -# Grab changes in blocks of this many revisions, unless otherwise requested -defaultBlockSize = 512 +# The block size is reduced automatically if required +defaultBlockSize = 1<<20 + +p4_access_checked = False def p4_build_cmd(cmd): """Build a suitable p4 command line. @@ -91,6 +93,13 @@ def p4_build_cmd(cmd): real_cmd = ' '.join(real_cmd) + ' ' + cmd else: real_cmd += cmd + + # now check that we can actually talk to the server + global p4_access_checked + if not p4_access_checked: + p4_access_checked = True # suppress access checks in p4_check_access itself + p4_check_access() + return real_cmd def git_dir(path): @@ -264,6 +273,52 @@ def p4_system(cmd): if retcode: raise CalledProcessError(retcode, real_cmd) +def die_bad_access(s): + die("failure accessing depot: {0}".format(s.rstrip())) + +def p4_check_access(min_expiration=1): + """ Check if we can access Perforce - account still logged in + """ + results = p4CmdList(["login", "-s"]) + + if len(results) == 0: + # should never get here: always get either some results, or a p4ExitCode + assert("could not parse response from perforce") + + result = results[0] + + if 'p4ExitCode' in result: + # p4 returned non-zero status, e.g. P4PORT invalid, or p4 not in path + die_bad_access("could not run p4") + + code = result.get("code") + if not code: + # we get here if we couldn't connect and there was nothing to unmarshal + die_bad_access("could not connect") + + elif code == "stat": + expiry = result.get("TicketExpiration") + if expiry: + expiry = int(expiry) + if expiry > min_expiration: + # ok to carry on + return + else: + die_bad_access("perforce ticket expires in {0} seconds".format(expiry)) + + else: + # account without a timeout - all ok + return + + elif code == "error": + data = result.get("data") + if data: + die_bad_access("p4 error: {0}".format(data)) + else: + die_bad_access("unknown error") + else: + die_bad_access("unknown error code {0}".format(code)) + _p4_version_string = None def p4_version_string(): """Read the version string, showing just the last line, which @@ -511,10 +566,30 @@ def isModeExec(mode): # otherwise False. return mode[-3:] == "755" +class P4Exception(Exception): + """ Base class for exceptions from the p4 client """ + def __init__(self, exit_code): + self.p4ExitCode = exit_code + +class P4ServerException(P4Exception): + """ Base class for exceptions where we get some kind of marshalled up result from the server """ + def __init__(self, exit_code, p4_result): + super(P4ServerException, self).__init__(exit_code) + self.p4_result = p4_result + self.code = p4_result[0]['code'] + self.data = p4_result[0]['data'] + +class P4RequestSizeException(P4ServerException): + """ One of the maxresults or maxscanrows errors """ + def __init__(self, exit_code, p4_result, limit): + super(P4RequestSizeException, self).__init__(exit_code, p4_result) + self.limit = limit + def isModeExecChanged(src_mode, dst_mode): return isModeExec(src_mode) != isModeExec(dst_mode) -def p4CmdList(cmd, stdin=None, stdin_mode='w+b', cb=None, skip_info=False): +def p4CmdList(cmd, stdin=None, stdin_mode='w+b', cb=None, skip_info=False, + errors_as_exceptions=False): if isinstance(cmd,basestring): cmd = "-G " + cmd @@ -561,9 +636,25 @@ def p4CmdList(cmd, stdin=None, stdin_mode='w+b', cb=None, skip_info=False): pass exitCode = p4.wait() if exitCode != 0: - entry = {} - entry["p4ExitCode"] = exitCode - result.append(entry) + if errors_as_exceptions: + if len(result) > 0: + data = result[0].get('data') + if data: + m = re.search('Too many rows scanned \(over (\d+)\)', data) + if not m: + m = re.search('Request too large \(over (\d+)\)', data) + + if m: + limit = int(m.group(1)) + raise P4RequestSizeException(exitCode, result, limit) + + raise P4ServerException(exitCode, result) + else: + raise P4Exception(exitCode) + else: + entry = {} + entry["p4ExitCode"] = exitCode + result.append(entry) return result @@ -868,7 +959,7 @@ def p4ChangesForPaths(depotPaths, changeRange, requestedBlockSize): try: (changeStart, changeEnd) = p4ParseNumericChangeRange(parts) block_size = chooseBlockSize(requestedBlockSize) - except: + except ValueError: changeStart = parts[0][1:] changeEnd = parts[1] if requestedBlockSize: @@ -878,7 +969,8 @@ def p4ChangesForPaths(depotPaths, changeRange, requestedBlockSize): changes = set() # Retrieve changes a block at a time, to prevent running - # into a MaxResults/MaxScanRows error from the server. + # into a MaxResults/MaxScanRows error from the server. If + # we _do_ hit one of those errors, turn down the block size while True: cmd = ['changes'] @@ -892,10 +984,24 @@ def p4ChangesForPaths(depotPaths, changeRange, requestedBlockSize): for p in depotPaths: cmd += ["%s...@%s" % (p, revisionRange)] + # fetch the changes + try: + result = p4CmdList(cmd, errors_as_exceptions=True) + except P4RequestSizeException as e: + if not block_size: + block_size = e.limit + elif block_size > e.limit: + block_size = e.limit + else: + block_size = max(2, block_size // 2) + + if verbose: print("block size error, retrying with block size {0}".format(block_size)) + continue + except P4Exception as e: + die('Error retrieving changes description ({0})'.format(e.p4ExitCode)) + # Insert changes in chronological order - for entry in reversed(p4CmdList(cmd)): - if entry.has_key('p4ExitCode'): - die('Error retrieving changes descriptions ({})'.format(entry['p4ExitCode'])) + for entry in reversed(result): if not entry.has_key('change'): continue changes.add(int(entry['change'])) @@ -1363,7 +1469,14 @@ class P4Submit(Command, P4UserMap): optparse.make_option("--update-shelve", dest="update_shelve", action="append", type="int", metavar="CHANGELIST", help="update an existing shelved changelist, implies --shelve, " - "repeat in-order for multiple shelved changelists") + "repeat in-order for multiple shelved changelists"), + optparse.make_option("--commit", dest="commit", metavar="COMMIT", + help="submit only the specified commit(s), one commit or xxx..xxx"), + optparse.make_option("--disable-rebase", dest="disable_rebase", action="store_true", + help="Disable rebase after submit is completed. Can be useful if you " + "work from a local git branch that is not master"), + optparse.make_option("--disable-p4sync", dest="disable_p4sync", action="store_true", + help="Skip Perforce sync of p4/master after submit or shelve"), ] self.description = "Submit changes from git to the perforce depot." self.usage += " [name of git branch to submit into perforce depot]" @@ -1373,6 +1486,9 @@ class P4Submit(Command, P4UserMap): self.dry_run = False self.shelve = False self.update_shelve = list() + self.commit = "" + self.disable_rebase = gitConfigBool("git-p4.disableRebase") + self.disable_p4sync = gitConfigBool("git-p4.disableP4Sync") self.prepare_p4_only = False self.conflict_behavior = None self.isWindows = (platform.system() == "Windows") @@ -2114,9 +2230,18 @@ class P4Submit(Command, P4UserMap): else: committish = 'HEAD' - for line in read_pipe_lines(["git", "rev-list", "--no-merges", "%s..%s" % (self.origin, committish)]): - commits.append(line.strip()) - commits.reverse() + if self.commit != "": + if self.commit.find("..") != -1: + limits_ish = self.commit.split("..") + for line in read_pipe_lines(["git", "rev-list", "--no-merges", "%s..%s" % (limits_ish[0], limits_ish[1])]): + commits.append(line.strip()) + commits.reverse() + else: + commits.append(self.commit) + else: + for line in read_pipe_lines(["git", "rev-list", "--no-merges", "%s..%s" % (self.origin, committish)]): + commits.append(line.strip()) + commits.reverse() if self.preserveUser or gitConfigBool("git-p4.skipUserNameCheck"): self.checkAuthorship = False @@ -2224,10 +2349,14 @@ class P4Submit(Command, P4UserMap): sync = P4Sync() if self.branch: sync.branch = self.branch - sync.run([]) + if self.disable_p4sync: + sync.sync_origin_only() + else: + sync.run([]) - rebase = P4Rebase() - rebase.rebase() + if not self.disable_rebase: + rebase = P4Rebase() + rebase.rebase() else: if len(applied) == 0: @@ -3307,6 +3436,14 @@ class P4Sync(Command, P4UserMap): print self.gitError.read() sys.exit(1) + def sync_origin_only(self): + if self.syncWithOrigin: + self.hasOrigin = originP4BranchesExist() + if self.hasOrigin: + if not self.silent: + print 'Syncing with origin first, using "git fetch origin"' + system("git fetch origin") + def importHeadRevision(self, revision): print "Doing initial import of %s from revision %s into %s" % (' '.join(self.depotPaths), revision, self.branch) @@ -3385,12 +3522,7 @@ class P4Sync(Command, P4UserMap): else: self.refPrefix = "refs/heads/p4/" - if self.syncWithOrigin: - self.hasOrigin = originP4BranchesExist() - if self.hasOrigin: - if not self.silent: - print 'Syncing with origin first, using "git fetch origin"' - system("git fetch origin") + self.sync_origin_only() branch_arg_given = bool(self.branch) if len(self.branch) == 0: diff --git a/merge-recursive.c b/merge-recursive.c index 5eb907f46e..f110e1c5ec 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -2211,18 +2211,18 @@ static struct hashmap *get_directory_renames(struct diff_queue_struct *pairs, static struct dir_rename_entry *check_dir_renamed(const char *path, struct hashmap *dir_renames) { - char temp[PATH_MAX]; + char *temp = xstrdup(path); char *end; - struct dir_rename_entry *entry; + struct dir_rename_entry *entry = NULL;; - strcpy(temp, path); while ((end = strrchr(temp, '/'))) { *end = '\0'; entry = dir_rename_find_entry(dir_renames, temp); if (entry) - return entry; + break; } - return NULL; + free(temp); + return entry; } static void compute_collisions(struct hashmap *collisions, diff --git a/pack-bitmap.c b/pack-bitmap.c index 06771113fb..18f8b22aeb 100644 --- a/pack-bitmap.c +++ b/pack-bitmap.c @@ -120,7 +120,7 @@ static struct ewah_bitmap *read_bitmap_1(struct bitmap_index *index) { struct ewah_bitmap *b = ewah_pool_new(); - int bitmap_size = ewah_read_mmap(b, + ssize_t bitmap_size = ewah_read_mmap(b, index->map + index->map_pos, index->map_size - index->map_pos); diff --git a/packfile.c b/packfile.c index 1a714fbde9..7cd45aa4b2 100644 --- a/packfile.c +++ b/packfile.c @@ -1454,6 +1454,9 @@ static void *unpack_compressed_entry(struct packed_git *p, return NULL; } + /* versions of zlib can clobber unconsumed portion of outbuf */ + buffer[size] = '\0'; + return buffer; } diff --git a/sequencer.c b/sequencer.c index cca968043e..4034c0461b 100644 --- a/sequencer.c +++ b/sequencer.c @@ -784,7 +784,7 @@ static int run_git_commit(const char *defmsg, struct replay_opts *opts, struct child_process cmd = CHILD_PROCESS_INIT; const char *value; - if (flags & CREATE_ROOT_COMMIT) { + if ((flags & CREATE_ROOT_COMMIT) && !(flags & AMEND_MSG)) { struct strbuf msg = STRBUF_INIT, script = STRBUF_INIT; const char *author = is_rebase_i(opts) ? read_author_ident(&script) : NULL; diff --git a/sha1-file.c b/sha1-file.c index 555e780f4b..695e5c6276 100644 --- a/sha1-file.c +++ b/sha1-file.c @@ -610,7 +610,7 @@ void add_to_alternates_memory(const char *reference) /* * Compute the exact path an alternate is at and returns it. In case of * error NULL is returned and the human readable error is added to `err` - * `path` may be relative and should point to $GITDIR. + * `path` may be relative and should point to $GIT_DIR. * `err` must not be null. */ char *compute_alternate_path(const char *path, struct strbuf *err) diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh index 69ea8202f4..08467982f6 100755 --- a/t/t3200-branch.sh +++ b/t/t3200-branch.sh @@ -885,7 +885,7 @@ test_expect_success 'test --unset-upstream on a particular branch' ' test_must_fail git config branch.my14.merge ' -test_expect_success '--set-upstream fails' ' +test_expect_success 'disabled option --set-upstream fails' ' test_must_fail git branch --set-upstream origin/master ' diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index c65826ddac..352a52e59d 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -971,6 +971,16 @@ test_expect_success 'rebase -i --root fixup root commit' ' test 0 = $(git cat-file commit HEAD | grep -c ^parent\ ) ' +test_expect_success 'rebase -i --root reword root commit' ' + test_when_finished "test_might_fail git rebase --abort" && + git checkout -b reword-root-branch master && + set_fake_editor && + FAKE_LINES="reword 1 2" FAKE_COMMIT_MESSAGE="A changed" \ + git rebase -i --root && + git show HEAD^ | grep "A changed" && + test -z "$(git show -s --format=%p HEAD^)" +' + test_expect_success C_LOCALE_OUTPUT 'rebase --edit-todo does not work on non-interactive rebase' ' git reset --hard && git checkout conflict-branch && diff --git a/t/t5310-pack-bitmaps.sh b/t/t5310-pack-bitmaps.sh index 423c0a475f..2d22a17c4a 100755 --- a/t/t5310-pack-bitmaps.sh +++ b/t/t5310-pack-bitmaps.sh @@ -331,4 +331,17 @@ test_expect_success 'pack reuse respects --incremental' ' git show-index <empty.idx >actual && test_cmp expect actual ' + +test_expect_success 'truncated bitmap fails gracefully' ' + git repack -ad && + git rev-list --use-bitmap-index --count --all >expect && + bitmap=$(ls .git/objects/pack/*.bitmap) && + test_when_finished "rm -f $bitmap" && + head -c 512 <$bitmap >$bitmap.tmp && + mv -f $bitmap.tmp $bitmap && + git rev-list --use-bitmap-index --count --all >actual 2>stderr && + test_cmp expect actual && + test_i18ngrep corrupt stderr +' + test_done diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh index 2f532529b8..812db137b8 100755 --- a/t/t7400-submodule-basic.sh +++ b/t/t7400-submodule-basic.sh @@ -126,8 +126,10 @@ test_expect_success 'submodule add' ' test_cmp empty untracked ' -test_create_repo parent && -test_commit -C parent one +test_expect_success 'setup parent and one repository' ' + test_create_repo parent && + test_commit -C parent one +' test_expect_success 'redirected submodule add does not show progress' ' git -C addtest submodule add "file://$submodurl/parent" submod-redirected \ diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh index 6f083c4d68..9e0d31700e 100755 --- a/t/t7406-submodule-update.sh +++ b/t/t7406-submodule-update.sh @@ -65,7 +65,7 @@ test_expect_success 'setup a submodule tree' ' git commit -m "none" ) && git clone . recursivesuper && - ( cd recursivesuper + ( cd recursivesuper && git submodule add ../super super ) ' @@ -245,13 +245,13 @@ test_expect_success 'submodule update --remote should fetch upstream changes wit ( cd super && git submodule update --remote --force submodule && - git -C submodule log -1 --oneline >actual - git -C ../submodule log -1 --oneline master >expect + git -C submodule log -1 --oneline >actual && + git -C ../submodule log -1 --oneline master >expect && test_cmp expect actual && git checkout -b test-branch && git submodule update --remote --force submodule && - git -C submodule log -1 --oneline >actual - git -C ../submodule log -1 --oneline test-branch >expect + git -C submodule log -1 --oneline >actual && + git -C ../submodule log -1 --oneline test-branch >expect && test_cmp expect actual && git checkout master && git branch -d test-branch && @@ -891,7 +891,7 @@ test_expect_success 'submodule update properly revives a moved submodule' ' rm -rf submodule2 && mkdir -p "moved/sub module" && git update-index --add --cacheinfo 160000 $H "moved/sub module" && - git config -f .gitmodules submodule.submodule2.path "moved/sub module" + git config -f .gitmodules submodule.submodule2.path "moved/sub module" && git commit -am "post move" && git submodule update && git status | sed "s/$H2/XXX/" >actual && diff --git a/t/t9807-git-p4-submit.sh b/t/t9807-git-p4-submit.sh index 71cae2874d..2325599ee6 100755 --- a/t/t9807-git-p4-submit.sh +++ b/t/t9807-git-p4-submit.sh @@ -155,6 +155,46 @@ test_expect_success 'allow submit from branch with same revision but different n ) ' +# make two commits, but tell it to apply only one + +test_expect_success 'submit --commit one' ' + test_when_finished cleanup_git && + git p4 clone --dest="$git" //depot && + ( + cd "$git" && + test_commit "file9" && + test_commit "file10" && + git config git-p4.skipSubmitEdit true && + git p4 submit --commit HEAD + ) && + ( + cd "$cli" && + test_path_is_missing "file9.t" && + test_path_is_file "file10.t" + ) +' + +# make three commits, but tell it to apply only range + +test_expect_success 'submit --commit range' ' + test_when_finished cleanup_git && + git p4 clone --dest="$git" //depot && + ( + cd "$git" && + test_commit "file11" && + test_commit "file12" && + test_commit "file13" && + git config git-p4.skipSubmitEdit true && + git p4 submit --commit HEAD~2..HEAD + ) && + ( + cd "$cli" && + test_path_is_missing "file11.t" && + test_path_is_file "file12.t" && + test_path_is_file "file13.t" + ) +' + # # Basic submit tests, the five handled cases # diff --git a/t/t9818-git-p4-block.sh b/t/t9818-git-p4-block.sh index 8840a183ac..ce7cb22ad3 100755 --- a/t/t9818-git-p4-block.sh +++ b/t/t9818-git-p4-block.sh @@ -129,6 +129,7 @@ test_expect_success 'Create a repo with multiple depot paths' ' ' test_expect_success 'Clone repo with multiple depot paths' ' + test_when_finished cleanup_git && ( cd "$git" && git p4 clone --changes-block-size=4 //depot/pathA@all //depot/pathB@all \ @@ -138,6 +139,13 @@ test_expect_success 'Clone repo with multiple depot paths' ' ) ' +test_expect_success 'Clone repo with self-sizing block size' ' + test_when_finished cleanup_git && + git p4 clone --changes-block-size=1000000 //depot@all --destination="$git" && + git -C "$git" log --oneline >log && + test_line_count \> 10 log +' + test_expect_success 'kill p4d' ' kill_p4d ' diff --git a/t/t9833-errors.sh b/t/t9833-errors.sh new file mode 100755 index 0000000000..9ba892de7a --- /dev/null +++ b/t/t9833-errors.sh @@ -0,0 +1,78 @@ +#!/bin/sh + +test_description='git p4 errors' + +. ./lib-git-p4.sh + +test_expect_success 'start p4d' ' + start_p4d +' + +test_expect_success 'add p4 files' ' + ( + cd "$cli" && + echo file1 >file1 && + p4 add file1 && + p4 submit -d "file1" + ) +' + +# after this test, the default user requires a password +test_expect_success 'error handling' ' + git p4 clone --dest="$git" //depot@all && + ( + cd "$git" && + P4PORT=: test_must_fail git p4 submit 2>errmsg + ) && + p4 passwd -P newpassword && + ( + P4PASSWD=badpassword test_must_fail git p4 clone //depot/foo 2>errmsg && + grep -q "failure accessing depot.*P4PASSWD" errmsg + ) +' + +test_expect_success 'ticket logged out' ' + P4TICKETS="$cli/tickets" && + echo "newpassword" | p4 login && + ( + cd "$git" && + test_commit "ticket-auth-check" && + p4 logout && + test_must_fail git p4 submit 2>errmsg && + grep -q "failure accessing depot" errmsg + ) +' + +test_expect_success 'create group with short ticket expiry' ' + P4TICKETS="$cli/tickets" && + echo "newpassword" | p4 login && + p4_add_user short_expiry_user && + p4 -u short_expiry_user passwd -P password && + p4 group -i <<-EOF && + Group: testgroup + Timeout: 3 + Users: short_expiry_user + EOF + + p4 users | grep short_expiry_user +' + +test_expect_success 'git operation with expired ticket' ' + P4TICKETS="$cli/tickets" && + P4USER=short_expiry_user && + echo "password" | p4 login && + ( + cd "$git" && + git p4 sync && + sleep 5 && + test_must_fail git p4 sync 2>errmsg && + grep "failure accessing depot" errmsg + ) +' + +test_expect_success 'kill p4d' ' + kill_p4d +' + + +test_done |
