2
2
//! authentication/cloning.
3
3
4
4
use crate :: core:: { GitReference , Verbosity } ;
5
- use crate :: sources:: git:: fetch:: { History , RemoteKind } ;
5
+ use crate :: sources:: git:: fetch:: RemoteKind ;
6
6
use crate :: sources:: git:: oxide;
7
7
use crate :: sources:: git:: oxide:: cargo_config_to_gitoxide_overrides;
8
8
use crate :: util:: errors:: CargoResult ;
@@ -97,32 +97,25 @@ impl GitRemote {
97
97
// if we can. If that can successfully load our revision then we've
98
98
// populated the database with the latest version of `reference`, so
99
99
// return that database and the rev we resolve to.
100
- let remote_kind = if locked_rev. is_some ( ) || matches ! ( reference, GitReference :: Rev ( _) ) {
101
- RemoteKind :: GitDependencyForbidShallow
102
- } else {
103
- RemoteKind :: GitDependency
104
- } ;
105
100
if let Some ( mut db) = db {
106
- let history = remote_kind. to_history ( db. repo . is_shallow ( ) , cargo_config) ;
101
+ let shallow =
102
+ RemoteKind :: GitDependency . to_shallow_setting ( db. repo . is_shallow ( ) , cargo_config) ;
107
103
fetch (
108
104
& mut db. repo ,
109
105
self . url . as_str ( ) ,
110
106
reference,
111
107
cargo_config,
112
- history,
108
+ shallow,
109
+ locked_rev,
113
110
)
114
111
. with_context ( || format ! ( "failed to fetch into: {}" , into. display( ) ) ) ?;
115
- match locked_rev {
116
- Some ( rev) => {
117
- if db. contains ( rev) {
118
- return Ok ( ( db, rev) ) ;
119
- }
120
- }
121
- None => {
122
- if let Ok ( rev) = reference. resolve ( & db. repo ) {
123
- return Ok ( ( db, rev) ) ;
124
- }
125
- }
112
+
113
+ let resolved_commit_hash = match locked_rev {
114
+ Some ( rev) => db. contains ( rev) . then_some ( rev) ,
115
+ None => reference. resolve ( & db. repo ) . ok ( ) ,
116
+ } ;
117
+ if let Some ( rev) = resolved_commit_hash {
118
+ return Ok ( ( db, rev) ) ;
126
119
}
127
120
}
128
121
@@ -134,13 +127,14 @@ impl GitRemote {
134
127
}
135
128
paths:: create_dir_all ( into) ?;
136
129
let mut repo = init ( into, true ) ?;
137
- let history = remote_kind . to_history ( repo. is_shallow ( ) , cargo_config) ;
130
+ let shallow = RemoteKind :: GitDependency . to_shallow_setting ( repo. is_shallow ( ) , cargo_config) ;
138
131
fetch (
139
132
& mut repo,
140
133
self . url . as_str ( ) ,
141
134
reference,
142
135
cargo_config,
143
- history,
136
+ shallow,
137
+ locked_rev,
144
138
)
145
139
. with_context ( || format ! ( "failed to clone into: {}" , into. display( ) ) ) ?;
146
140
let rev = match locked_rev {
@@ -462,8 +456,9 @@ impl<'a> GitCheckout<'a> {
462
456
cargo_config
463
457
. shell ( )
464
458
. status ( "Updating" , format ! ( "git submodule `{}`" , url) ) ?;
465
- let history = RemoteKind :: GitDependency . to_history ( repo. is_shallow ( ) , cargo_config) ;
466
- fetch ( & mut repo, & url, & reference, cargo_config, history) . with_context ( || {
459
+ let shallow =
460
+ RemoteKind :: GitDependency . to_shallow_setting ( repo. is_shallow ( ) , cargo_config) ;
461
+ fetch ( & mut repo, & url, & reference, cargo_config, shallow, None ) . with_context ( || {
467
462
format ! (
468
463
"failed to fetch submodule `{}` from {}" ,
469
464
child. name( ) . unwrap_or( "" ) ,
@@ -842,7 +837,8 @@ pub fn fetch(
842
837
orig_url : & str ,
843
838
reference : & GitReference ,
844
839
config : & Config ,
845
- history : History ,
840
+ shallow : gix:: remote:: fetch:: Shallow ,
841
+ locked_rev : Option < git2:: Oid > ,
846
842
) -> CargoResult < ( ) > {
847
843
if config. frozen ( ) {
848
844
anyhow:: bail!(
@@ -855,14 +851,20 @@ pub fn fetch(
855
851
}
856
852
857
853
// If we're fetching from GitHub, attempt GitHub's special fast path for
858
- // testing if we've already got an up-to-date copy of the repository
859
- let oid_to_fetch = match github_fast_path ( repo, orig_url, reference, config) {
860
- Ok ( FastPathRev :: UpToDate ) => return Ok ( ( ) ) ,
861
- Ok ( FastPathRev :: NeedsFetch ( rev) ) => Some ( rev) ,
862
- Ok ( FastPathRev :: Indeterminate ) => None ,
863
- Err ( e) => {
864
- debug ! ( "failed to check github {:?}" , e) ;
865
- None
854
+ // testing if we've already got an up-to-date copy of the repository.
855
+ // With shallow histories this is a bit fuzzy, and we opt-out for now.
856
+ let is_shallow = repo. is_shallow ( ) || !matches ! ( shallow, gix:: remote:: fetch:: Shallow :: NoChange ) ;
857
+ let oid_to_fetch = if is_shallow {
858
+ None
859
+ } else {
860
+ match github_fast_path ( repo, orig_url, reference, config) {
861
+ Ok ( FastPathRev :: UpToDate ) => return Ok ( ( ) ) ,
862
+ Ok ( FastPathRev :: NeedsFetch ( rev) ) => Some ( rev) ,
863
+ Ok ( FastPathRev :: Indeterminate ) => None ,
864
+ Err ( e) => {
865
+ debug ! ( "failed to check github {:?}" , e) ;
866
+ None
867
+ }
866
868
}
867
869
} ;
868
870
@@ -881,32 +883,44 @@ pub fn fetch(
881
883
// The `+` symbol on the refspec means to allow a forced (fast-forward)
882
884
// update which is needed if there is ever a force push that requires a
883
885
// fast-forward.
884
- match reference {
885
- // For branches and tags we can fetch simply one reference and copy it
886
- // locally, no need to fetch other branches/tags.
887
- GitReference :: Branch ( b) => {
888
- refspecs. push ( format ! ( "+refs/heads/{0}:refs/remotes/origin/{0}" , b) ) ;
889
- }
890
- GitReference :: Tag ( t) => {
891
- refspecs. push ( format ! ( "+refs/tags/{0}:refs/remotes/origin/tags/{0}" , t) ) ;
892
- }
893
-
894
- GitReference :: DefaultBranch => {
895
- refspecs. push ( String :: from ( "+HEAD:refs/remotes/origin/HEAD" ) ) ;
896
- }
886
+ if let Some ( rev) =
887
+ locked_rev. filter ( |_| !matches ! ( shallow, gix:: remote:: fetch:: Shallow :: NoChange ) )
888
+ {
889
+ // If we want a specific revision and know about, obtain that specifically.
890
+ refspecs. push ( format ! ( "+{0}:refs/remotes/origin/HEAD" , rev) ) ;
891
+ } else {
892
+ match reference {
893
+ // For branches and tags we can fetch simply one reference and copy it
894
+ // locally, no need to fetch other branches/tags.
895
+ GitReference :: Branch ( b) => {
896
+ refspecs. push ( format ! ( "+refs/heads/{0}:refs/remotes/origin/{0}" , b) ) ;
897
+ }
898
+ GitReference :: Tag ( t) => {
899
+ refspecs. push ( format ! ( "+refs/tags/{0}:refs/remotes/origin/tags/{0}" , t) ) ;
900
+ }
897
901
898
- GitReference :: Rev ( rev) => {
899
- if rev. starts_with ( "refs/" ) {
900
- refspecs. push ( format ! ( "+{0}:{0}" , rev) ) ;
901
- } else if let Some ( oid_to_fetch) = oid_to_fetch {
902
- refspecs. push ( format ! ( "+{0}:refs/commit/{0}" , oid_to_fetch) ) ;
903
- } else {
904
- // We don't know what the rev will point to. To handle this
905
- // situation we fetch all branches and tags, and then we pray
906
- // it's somewhere in there.
907
- refspecs. push ( String :: from ( "+refs/heads/*:refs/remotes/origin/*" ) ) ;
902
+ GitReference :: DefaultBranch => {
908
903
refspecs. push ( String :: from ( "+HEAD:refs/remotes/origin/HEAD" ) ) ;
909
- tags = true ;
904
+ }
905
+
906
+ GitReference :: Rev ( rev) => {
907
+ if rev. starts_with ( "refs/" ) {
908
+ refspecs. push ( format ! ( "+{0}:{0}" , rev) ) ;
909
+ } else if let Some ( oid_to_fetch) = oid_to_fetch {
910
+ refspecs. push ( format ! ( "+{0}:refs/commit/{0}" , oid_to_fetch) ) ;
911
+ } else if is_shallow && git2:: Oid :: from_str ( & rev) . is_ok ( ) {
912
+ // There is a specific commit to fetch and we will just do so in shallow-mode only
913
+ // to not disturb the previous logic. Note that with typical settings for shallowing,
914
+ // we will just fetch a specific slice of the history.
915
+ refspecs. push ( format ! ( "+{0}:refs/remotes/origin/HEAD" , rev) ) ;
916
+ } else {
917
+ // We don't know what the rev will point to. To handle this
918
+ // situation we fetch all branches and tags, and then we pray
919
+ // it's somewhere in there.
920
+ refspecs. push ( String :: from ( "+refs/heads/*:refs/remotes/origin/*" ) ) ;
921
+ refspecs. push ( String :: from ( "+HEAD:refs/remotes/origin/HEAD" ) ) ;
922
+ tags = true ;
923
+ }
910
924
}
911
925
}
912
926
}
@@ -986,7 +1000,7 @@ pub fn fetch(
986
1000
) ;
987
1001
let outcome = connection
988
1002
. prepare_fetch ( & mut progress, gix:: remote:: ref_map:: Options :: default ( ) ) ?
989
- . with_shallow ( history . clone ( ) . into ( ) )
1003
+ . with_shallow ( shallow . clone ( ) . into ( ) )
990
1004
. receive ( & mut progress, should_interrupt) ?;
991
1005
Ok ( outcome)
992
1006
} ) ;
0 commit comments