1
+ use std:: path:: PathBuf ;
2
+ use std:: process:: Command ;
1
3
use std:: str;
2
4
3
5
/// This macro creates the version string during compilation from the
@@ -32,6 +34,7 @@ macro_rules! get_version_info {
32
34
#[ macro_export]
33
35
macro_rules! setup_version_info {
34
36
( ) => { {
37
+ let _ = $crate:: rerun_if_git_changes( ) ;
35
38
println!(
36
39
"cargo:rustc-env=GIT_HASH={}" ,
37
40
$crate:: get_commit_hash( ) . unwrap_or_default( )
@@ -41,6 +44,7 @@ macro_rules! setup_version_info {
41
44
$crate:: get_commit_date( ) . unwrap_or_default( )
42
45
) ;
43
46
println!( "cargo:rustc-env=RUSTC_RELEASE_CHANNEL={}" , $crate:: get_channel( ) ) ;
47
+ panic!( )
44
48
} } ;
45
49
}
46
50
@@ -100,19 +104,42 @@ impl std::fmt::Debug for VersionInfo {
100
104
}
101
105
102
106
#[ must_use]
103
- pub fn get_commit_hash ( ) -> Option < String > {
104
- let output = std:: process:: Command :: new ( "git" )
105
- . args ( [ "rev-parse" , "HEAD" ] )
107
+ pub fn rerun_if_git_changes ( ) -> Option < ( ) > {
108
+ // Make sure we get rerun when the git commit changes.
109
+ // First, find the `HEAD` file. This should work even with worktrees.
110
+ let output = Command :: new ( "git" ) . args ( [ "rev-parse" , "--git-dir" ] ) . output ( ) . ok ( ) ?;
111
+ let stdout = output. status . success ( ) . then_some ( output. stdout ) ?;
112
+ let git_dir = PathBuf :: from ( String :: from_utf8 ( stdout) . ok ( ) ?. trim ( ) ) ;
113
+ // Read the HEAD file to determine the name of the current ref.
114
+ let git_head_file = git_dir. join ( "HEAD" ) ;
115
+ let git_head_ref = String :: from_utf8 ( std:: fs:: read ( & git_head_file) . ok ( ) ?) . ok ( ) ?;
116
+ let git_head_ref = git_head_ref. strip_prefix ( "ref:" ) ?. trim ( ) ;
117
+ // Find the directory that stores the ref files.
118
+ let output = Command :: new ( "git" )
119
+ . args ( [ "rev-parse" , "--git-common-dir" ] )
106
120
. output ( )
107
121
. ok ( ) ?;
122
+ let stdout = output. status . success ( ) . then_some ( output. stdout ) ?;
123
+ let git_common_dir = PathBuf :: from ( String :: from_utf8 ( stdout) . ok ( ) ?. trim ( ) ) ;
124
+ // Determine the file where the target of that ref is stored.
125
+ let git_head_ref_file = git_common_dir. join ( git_head_ref) ;
126
+
127
+ println ! ( "cargo::rerun-if-changed={}" , git_head_file. display( ) ) ;
128
+ println ! ( "cargo::rerun-if-changed={}" , git_head_ref_file. display( ) ) ;
129
+ Some ( ( ) )
130
+ }
131
+
132
+ #[ must_use]
133
+ pub fn get_commit_hash ( ) -> Option < String > {
134
+ let output = Command :: new ( "git" ) . args ( [ "rev-parse" , "HEAD" ] ) . output ( ) . ok ( ) ?;
108
135
let mut stdout = output. status . success ( ) . then_some ( output. stdout ) ?;
109
136
stdout. truncate ( 10 ) ;
110
137
String :: from_utf8 ( stdout) . ok ( )
111
138
}
112
139
113
140
#[ must_use]
114
141
pub fn get_commit_date ( ) -> Option < String > {
115
- let output = std :: process :: Command :: new ( "git" )
142
+ let output = Command :: new ( "git" )
116
143
. args ( [ "log" , "-1" , "--date=short" , "--pretty=format:%cd" ] )
117
144
. output ( )
118
145
. ok ( ) ?;
0 commit comments