@@ -4,6 +4,7 @@ const RUST_SRC_URL: &str = "https://github.com/rust-lang/rust";
44const RUST_SRC_REPO : Option < & str > = option_env ! ( "RUST_SRC_REPO" ) ;
55
66use std:: env;
7+ use std:: ops:: Deref ;
78use std:: path:: Path ;
89
910use chrono:: { TimeZone , Utc } ;
@@ -25,14 +26,29 @@ impl Commit {
2526 }
2627}
2728
28- fn lookup_rev < ' rev > ( repo : & ' rev Repository , rev : & str ) -> Result < Git2Commit < ' rev > , Error > {
29+ struct RustcRepo {
30+ repository : Repository ,
31+ origin_remote : String ,
32+ }
33+
34+ impl Deref for RustcRepo {
35+ type Target = Repository ;
36+
37+ fn deref ( & self ) -> & Self :: Target {
38+ & self . repository
39+ }
40+ }
41+
42+ fn lookup_rev < ' rev > ( repo : & ' rev RustcRepo , rev : & str ) -> Result < Git2Commit < ' rev > , Error > {
2943 let revision = repo. revparse_single ( rev) ?;
3044
3145 // Find the merge-base between the revision and master.
3246 // If revision is a normal commit contained in master, the merge-base will be the commit itself.
3347 // If revision is a tag (e.g. a release version), the merge-base will contain the latest master
3448 // commit contained in that tag.
35- let master_id = repo. revparse_single ( "origin/master" ) ?. id ( ) ;
49+ let master_id = repo
50+ . revparse_single ( & format ! ( "{}/master" , repo. origin_remote) ) ?
51+ . id ( ) ;
3652 let revision_id = revision
3753 . as_tag ( )
3854 . map ( |tag| tag. target_id ( ) )
@@ -46,36 +62,70 @@ fn lookup_rev<'rev>(repo: &'rev Repository, rev: &str) -> Result<Git2Commit<'rev
4662 bail ! ( "Could not find a commit for revision specifier '{}'" , rev)
4763}
4864
49- fn get_repo ( ) -> Result < Repository , Error > {
50- fn open ( repo : & Path ) -> Result < Repository , Error > {
51- eprintln ! ( "refreshing repository at {:?}" , repo) ;
65+ fn get_repo ( ) -> Result < RustcRepo , Error > {
66+ fn open ( path : & Path ) -> Result < ( Repository , String ) , Error > {
67+ eprintln ! ( "opening existing repository at {:?}" , path) ;
68+ let repo = Repository :: open ( path) ?;
69+
70+ let origin_remote = find_origin_remote ( & repo) ?;
71+ eprintln ! ( "Found origin remote under name `{origin_remote}`" ) ;
72+
73+ eprintln ! ( "refreshing repository at {:?}" , path) ;
5274 // This uses the CLI because libgit2 is quite slow to fetch a large repository.
5375 let status = std:: process:: Command :: new ( "git" )
5476 . arg ( "fetch" )
55- . arg ( RUST_SRC_URL )
56- . current_dir ( repo )
77+ . arg ( & origin_remote )
78+ . current_dir ( path )
5779 . status ( )
5880 . context ( format ! (
5981 "expected `git` command-line executable to be installed"
6082 ) ) ?;
6183 if !status. success ( ) {
6284 bail ! ( "git fetch failed exit status {}" , status) ;
6385 }
64- eprintln ! ( "opening existing repository at {:?}" , repo) ;
65- let repo = Repository :: open ( repo) ?;
66- Ok ( repo)
86+
87+ Ok ( ( repo, origin_remote) )
6788 }
6889
6990 let loc = Path :: new ( "rust.git" ) ;
70- match ( env:: var_os ( "RUST_SRC_REPO" ) , RUST_SRC_REPO ) {
91+ let ( repository , origin_remote ) = match ( env:: var_os ( "RUST_SRC_REPO" ) , RUST_SRC_REPO ) {
7192 ( Some ( repo) , _) => open ( Path :: new ( & repo) ) ,
7293 ( None , _) if loc. exists ( ) => open ( loc) ,
7394 ( None , Some ( repo) ) => open ( Path :: new ( repo) ) ,
7495 _ => {
7596 eprintln ! ( "cloning rust repository" ) ;
76- Ok ( RepoBuilder :: new ( ) . bare ( true ) . clone ( RUST_SRC_URL , loc) ?)
97+ Ok ( (
98+ RepoBuilder :: new ( ) . bare ( true ) . clone ( RUST_SRC_URL , loc) ?,
99+ "origin" . to_string ( ) ,
100+ ) )
77101 }
78- }
102+ } ?;
103+
104+ Ok ( RustcRepo {
105+ repository,
106+ origin_remote,
107+ } )
108+ }
109+
110+ fn find_origin_remote ( repo : & Repository ) -> Result < String , Error > {
111+ repo. remotes ( ) ?
112+ . iter ( )
113+ . filter_map ( |name| name. and_then ( |name| repo. find_remote ( name) . ok ( ) ) )
114+ . find ( |remote| {
115+ remote
116+ . url ( )
117+ . map ( |url| url. contains ( RUST_SRC_URL ) )
118+ . unwrap_or ( false )
119+ } )
120+ . and_then ( |remote| remote. name ( ) . map ( |name| name. to_string ( ) ) )
121+ . ok_or_else ( || {
122+ failure:: format_err!(
123+ "rust-lang/rust remote not found. \
124+ Try adding a remote pointing to `{}` in the rust repository at `{}`.",
125+ RUST_SRC_URL ,
126+ repo. path( ) . display( )
127+ )
128+ } )
79129}
80130
81131pub ( crate ) fn get_commit ( sha : & str ) -> Result < Commit , Error > {
0 commit comments