Update git index before running diff-index · rust-lang/rust@69da9af (original) (raw)

`@@ -143,14 +143,13 @@ pub fn check_path_modifications(

`

143

143

``

144

144

`` /// Returns true if any of the passed paths have changed since the base commit.

``

145

145

`pub fn has_changed_since(git_dir: &Path, base: &str, paths: &[&str]) -> bool {

`

146

``

`-

let mut git = Command::new("git");

`

147

``

`-

git.current_dir(git_dir);

`

``

146

`+

run_git_diff_index(Some(git_dir), |cmd| {

`

``

147

`+

cmd.args(["--quiet", base, "--"]).args(paths);

`

148

148

``

149

``

`-

git.args(["diff-index", "--quiet", base, "--"]).args(paths);

`

150

``

-

151

``

`-

// Exit code 0 => no changes

`

152

``

`-

// Exit code 1 => some changes were detected

`

153

``

`-

!git.status().expect("cannot run git diff-index").success()

`

``

149

`+

// Exit code 0 => no changes

`

``

150

`+

// Exit code 1 => some changes were detected

`

``

151

`+

!cmd.status().expect("cannot run git diff-index").success()

`

``

152

`+

})

`

154

153

`}

`

155

154

``

156

155

`` /// Returns the latest upstream commit that modified target_paths, or None if no such commit

``

`@@ -267,31 +266,49 @@ pub fn get_git_modified_files(

`

267

266

`return Err("No upstream commit was found".to_string());

`

268

267

`};

`

269

268

``

270

``

`-

let mut git = Command::new("git");

`

271

``

`-

if let Some(git_dir) = git_dir {

`

272

``

`-

git.current_dir(git_dir);

`

273

``

`-

}

`

274

``

`-

let files = output_result(git.args(["diff-index", "--name-status", merge_base.trim()]))?

`

275

``

`-

.lines()

`

276

``

`-

.filter_map(|f| {

`

277

``

`-

let (status, name) = f.trim().split_once(char::is_whitespace).unwrap();

`

278

``

`-

if status == "D" {

`

279

``

`-

None

`

280

``

`-

} else if Path::new(name).extension().map_or(extensions.is_empty(), |ext| {

`

281

``

`` -

// If there is no extension, we allow the path if extensions is empty

``

282

``

`` -

// If there is an extension, we allow it if extension is empty or it contains the

``

283

``

`-

// extension.

`

284

``

`-

extensions.is_empty() || extensions.contains(&ext.to_str().unwrap())

`

285

``

`-

}) {

`

286

``

`-

Some(name.to_owned())

`

287

``

`-

} else {

`

288

``

`-

None

`

289

``

`-

}

`

290

``

`-

})

`

291

``

`-

.collect();

`

``

269

`+

let files = run_git_diff_index(git_dir, |cmd| {

`

``

270

`+

output_result(cmd.args(["--name-status", merge_base.trim()]))

`

``

271

`+

})?

`

``

272

`+

.lines()

`

``

273

`+

.filter_map(|f| {

`

``

274

`+

let (status, name) = f.trim().split_once(char::is_whitespace).unwrap();

`

``

275

`+

if status == "D" {

`

``

276

`+

None

`

``

277

`+

} else if Path::new(name).extension().map_or(extensions.is_empty(), |ext| {

`

``

278

`` +

// If there is no extension, we allow the path if extensions is empty

``

``

279

`` +

// If there is an extension, we allow it if extension is empty or it contains the

``

``

280

`+

// extension.

`

``

281

`+

extensions.is_empty() || extensions.contains(&ext.to_str().unwrap())

`

``

282

`+

}) {

`

``

283

`+

Some(name.to_owned())

`

``

284

`+

} else {

`

``

285

`+

None

`

``

286

`+

}

`

``

287

`+

})

`

``

288

`+

.collect();

`

292

289

`Ok(files)

`

293

290

`}

`

294

291

``

``

292

`+

/// diff-index can return outdated information, because it does not update the git index.

`

``

293

`` +

/// This function uses update-index to update the index first, and then provides func with a

``

``

294

`` +

/// command prepared to run git diff-index.

``

``

295

`+

fn run_git_diff_index<F, T>(git_dir: Option<&Path>, func: F) -> T

`

``

296

`+

where

`

``

297

`+

F: FnOnce(&mut Command) -> T,

`

``

298

`+

{

`

``

299

`+

let git = || {

`

``

300

`+

let mut git = Command::new("git");

`

``

301

`+

if let Some(git_dir) = git_dir {

`

``

302

`+

git.current_dir(git_dir);

`

``

303

`+

}

`

``

304

`+

git

`

``

305

`+

};

`

``

306

+

``

307

`+

// We ignore the exit code, as it errors out when some files are modified.

`

``

308

`+

let _ = output_result(git().args(["update-index", "--refresh", "-q"]));

`

``

309

`+

func(git().arg("diff-index"))

`

``

310

`+

}

`

``

311

+

295

312

`/// Returns the files that haven't been added to git yet.

`

296

313

`pub fn get_git_untracked_files(git_dir: Option<&Path>) -> Result<Option<Vec>, String> {

`

297

314

`let mut git = Command::new("git");

`