def audit_git_path(ui, path): r"""Check for path components that case-fold to .git. >>> class fakeui(object): ... def configbool(*args): ... return False ... def warn(self, s): ... print s >>> u = fakeui() >>> audit_git_path(u, 'foo/git~100/wat') warning: path 'foo/git~100/wat' contains a dangerous path component. It may not be legal to check out in Git. It may also be rejected by some git server configurations. <BLANKLINE> >>> audit_git_path(u, u'foo/.gi\u200ct'.encode('utf-8')) warning: path 'foo/.gi\xe2\x80\x8ct' contains a dangerous path component. It may not be legal to check out in Git. It may also be rejected by some git server configurations. <BLANKLINE> >>> audit_git_path(u, 'this/is/safe') """ dangerous = False for c in path.split(os.path.sep): if compat.hfsignoreclean(c) == ".git": dangerous = True break elif "~" in c: base, tail = c.split("~", 1) if tail.isdigit() and base.upper().startswith("GIT"): dangerous = True break if dangerous: if compat.config(ui, "bool", "git", "blockdotgit"): raise hgutil.Abort( _("Refusing to export likely-dangerous path %r") % path, hint=_("If you need to continue, read about CVE-2014-9390 and " "then set '[git] blockdotgit = false' in your hgrc."), ) ui.warn( _("warning: path %r contains a dangerous path component.\n" "It may not be legal to check out in Git.\n" "It may also be rejected by some git server configurations.\n") % path)
def verify(ui, repo, hgctx): """verify that a Mercurial rev matches the corresponding Git rev Given a Mercurial revision that has a corresponding Git revision in the map, this attempts to answer whether that revision has the same contents as the corresponding Git revision. """ handler = repo.githandler gitsha = handler.map_git_get(hgctx.hex()) if not gitsha: # TODO deal better with commits in the middle of octopus merges raise hgutil.Abort( _("no git commit found for rev %s") % hgctx, hint=_("if this is an octopus merge, " "verify against the last rev"), ) try: gitcommit = handler.git.get_object(pycompat.encodeutf8(gitsha)) except KeyError: raise hgutil.Abort( _("git equivalent %s for rev %s not found!") % (gitsha, hgctx)) if not isinstance(gitcommit, Commit): raise hgutil.Abort( _("git equivalent %s for rev %s is not a commit!") % (gitsha, hgctx)) ui.status(_("verifying rev %s against git commit %s\n") % (hgctx, gitsha)) failed = False # TODO check commit message and other metadata dirkind = stat.S_IFDIR hgfiles = set(hgctx) gitfiles = set() i = 0 with progress.bar(ui, _("verify"), total=len(hgfiles)) as prog: for gitfile, dummy in diff_tree.walk_trees(handler.git.object_store, gitcommit.tree, None): if gitfile.mode == dirkind: continue # TODO deal with submodules if gitfile.mode == S_IFGITLINK: continue prog.value = i i += 1 gitfilepath = pycompat.decodeutf8(gitfile.path) gitfiles.add(gitfilepath) try: fctx = hgctx[gitfilepath] except error.LookupError: # we'll deal with this at the end continue hgflags = fctx.flags() gitflags = handler.convert_git_int_mode(gitfile.mode) if hgflags != gitflags: ui.write( _("file has different flags: %s (hg '%s', git '%s')\n") % (gitfilepath, hgflags, gitflags)) failed = True if fctx.data() != handler.git[gitfile.sha].data: ui.write(_("difference in: %s\n") % gitfilepath) failed = True if hgfiles != gitfiles: failed = True missing = gitfiles - hgfiles for f in sorted(missing): ui.write(_("file found in git but not hg: %s\n") % f) unexpected = hgfiles - gitfiles for f in sorted(unexpected): ui.write(_("file found in hg but not git: %s\n") % f) if failed: return 1 else: return 0
def inner(*args, **kwargs): try: return f(*args, **kwargs) except errors.NotGitRepository: raise hgutil.Abort("not a git repository")