@@ -25,7 +25,7 @@ use futures::{
2525 stream:: FuturesOrdered ,
2626} ;
2727use git:: {
28- BuildPermalinkParams , GitHostingProviderRegistry , Oid ,
28+ BuildPermalinkParams , GitHostingProviderRegistry , Oid , RunHook ,
2929 blame:: Blame ,
3030 parse_git_remote_url,
3131 repository:: {
@@ -433,6 +433,7 @@ impl GitStore {
433433 client. add_entity_request_handler ( Self :: handle_stash_apply) ;
434434 client. add_entity_request_handler ( Self :: handle_stash_drop) ;
435435 client. add_entity_request_handler ( Self :: handle_commit) ;
436+ client. add_entity_request_handler ( Self :: handle_run_hook) ;
436437 client. add_entity_request_handler ( Self :: handle_reset) ;
437438 client. add_entity_request_handler ( Self :: handle_show) ;
438439 client. add_entity_request_handler ( Self :: handle_load_commit_diff) ;
@@ -1982,6 +1983,22 @@ impl GitStore {
19821983 Ok ( proto:: Ack { } )
19831984 }
19841985
1986+ async fn handle_run_hook (
1987+ this : Entity < Self > ,
1988+ envelope : TypedEnvelope < proto:: RunGitHook > ,
1989+ mut cx : AsyncApp ,
1990+ ) -> Result < proto:: Ack > {
1991+ let repository_id = RepositoryId :: from_proto ( envelope. payload . repository_id ) ;
1992+ let repository_handle = Self :: repository_for_request ( & this, repository_id, & mut cx) ?;
1993+ let hook = RunHook :: from_proto ( envelope. payload . hook ) . context ( "invalid hook" ) ?;
1994+ repository_handle
1995+ . update ( & mut cx, |repository_handle, cx| {
1996+ repository_handle. run_hook ( hook, cx)
1997+ } ) ?
1998+ . await ??;
1999+ Ok ( proto:: Ack { } )
2000+ }
2001+
19852002 async fn handle_commit (
19862003 this : Entity < Self > ,
19872004 envelope : TypedEnvelope < proto:: Commit > ,
@@ -4262,19 +4279,49 @@ impl Repository {
42624279 } )
42634280 }
42644281
4282+ pub fn run_hook ( & mut self , hook : RunHook , _cx : & mut App ) -> oneshot:: Receiver < Result < ( ) > > {
4283+ let id = self . id ;
4284+ self . send_job (
4285+ Some ( format ! ( "git hook {}" , hook. as_str( ) ) . into ( ) ) ,
4286+ move |git_repo, _cx| async move {
4287+ match git_repo {
4288+ RepositoryState :: Local {
4289+ backend,
4290+ environment,
4291+ } => backend. run_hook ( hook, environment. clone ( ) ) . await ,
4292+ RepositoryState :: Remote { project_id, client } => {
4293+ client
4294+ . request ( proto:: RunGitHook {
4295+ project_id : project_id. 0 ,
4296+ repository_id : id. to_proto ( ) ,
4297+ hook : hook. to_proto ( ) ,
4298+ } )
4299+ . await ?;
4300+
4301+ Ok ( ( ) )
4302+ }
4303+ }
4304+ } ,
4305+ )
4306+ }
4307+
42654308 pub fn commit (
42664309 & mut self ,
42674310 message : SharedString ,
42684311 name_and_email : Option < ( SharedString , SharedString ) > ,
42694312 options : CommitOptions ,
42704313 askpass : AskPassDelegate ,
4271- _cx : & mut App ,
4314+ cx : & mut App ,
42724315 ) -> oneshot:: Receiver < Result < ( ) > > {
42734316 let id = self . id ;
42744317 let askpass_delegates = self . askpass_delegates . clone ( ) ;
42754318 let askpass_id = util:: post_inc ( & mut self . latest_askpass_id ) ;
42764319
4320+ let rx = self . run_hook ( RunHook :: PreCommit , cx) ;
4321+
42774322 self . send_job ( Some ( "git commit" . into ( ) ) , move |git_repo, _cx| async move {
4323+ rx. await ??;
4324+
42784325 match git_repo {
42794326 RepositoryState :: Local {
42804327 backend,
0 commit comments