1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798(*
* Copyright (c) 2013-2017 Thomas Gazagnaire <thomas@gazagnaire.org>
* and Romain Calascibetta <romain.calascibetta@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)moduleSHA1=Digestif.SHA1openLwt.InfixmoduleLog=structletsrc=Logs.Src.create"git.search"~doc:"logs git's internal search computation"include(valLogs.src_logsrc:Logs.LOG)endtypepred=[`CommitofSHA1.t|`Tagofstring*SHA1.t|`Treeofstring*SHA1.t*Git_store.Tree.perm|`Tree_rootofSHA1.t]letpredth=lettagt=`Tag(Git_store.Tag.tagt,Git_store.Tag.objt)inLog.debug(funl->l~header:"predecessor""Read the object: %a."SHA1.pph);matchGit_store.read_exnthwith|Git_store.Object.Blob_->Lwt.return[]|Git_store.Object.Commitc->beginGit_store.is_shallowedth>|=function|true->[`Tree_root(Git_store.Commit.treec)]|false->`Tree_root(Git_store.Commit.treec)::List.map(funx->`Commitx)(Git_store.Commit.parentsc)end|Git_store.Object.Tagt->Lwt.return[tagt]|Git_store.Object.Treet->letlst=List.map(fun{Git_store.Tree.name;node;perm}->`Tree(name,node,perm))(Git_store.Tree.to_listt)inLwt.returnlsttypepath=[`Tagofstring*path|`Commitofpath|`Pathofstringlist](* let _find_commit = List.find_map (function `Commit x -> Some x | _ -> None) *)letfind_tree_root:predlist->SHA1.toption=List.find_map(function`Tree_rootx->Somex|_->None)letfind_tagl=List.find_map(function|`Tag(s,x)->ifl=sthenSomexelseNone|_->None)letfind_treelelts=List.find_map(function|`Tree(s,x,perm)->ifs=lthenSome(x,perm)elseNone|_->None)eltsletrecfindthashpath=matchpathwith|`Path[]->(* TODO(reynir): I think we can synthesize [`Dir] here. Is this intuition correct?! *)Lwt.return(Some(`Dir,hash))|`Tag(l,p)->(predthash>>=funpreds->matchfind_taglpredswith|None->Lwt.return_none|Somes->(find[@tailcall])tsp)|`Commitp->(predthash>>=funpreds->matchfind_tree_rootpredswith|None->Lwt.return_none|Somes->(find[@tailcall])tsp)|`Path(h::p)->(predthash>>=funpreds->matchfind_treehpreds,pwith|None,_->Lwt.return_none|Some(s,_),_::_->(find[@tailcall])ts(`Pathp)|Some(s,perm),[]->Lwt.return(Some(perm,s)))(* XXX: can do one less look-up *)letmemthpath=findthpath>>=function|None->Lwt.returnfalse|Some_->Lwt.returntrue