From 9a6e5d4097a820a2128397286efc77c1196bfd29 Mon Sep 17 00:00:00 2001 From: Benjamin Tan Date: Sat, 13 Jul 2024 20:29:13 +0800 Subject: [PATCH 1/5] cargo: bump `git2` to 0.19.0 This includes a bump of `libgit2` to v1.8.1. --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- cli/tests/test_git_push.rs | 2 ++ lib/src/git.rs | 7 ++++++- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1dbaf1d9568..422c0328a66 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -967,9 +967,9 @@ checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" [[package]] name = "git2" -version = "0.18.3" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "232e6a7bfe35766bf715e55a88b39a700596c0ccfd88cd3680b4cdb40d66ef70" +checksum = "b903b73e45dc0c6c596f2d37eccece7c1c8bb6e4407b001096387c63d0d93724" dependencies = [ "bitflags 2.6.0", "libc", @@ -2019,9 +2019,9 @@ checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libgit2-sys" -version = "0.16.2+1.7.2" +version = "0.17.0+1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee4126d8b4ee5c9d9ea891dd875cfdc1e9d0950437179104b183d7d8a74d24e8" +checksum = "10472326a8a6477c3c20a64547b0059e4b0d086869eee31e6d7da728a8eb7224" dependencies = [ "cc", "libc", diff --git a/Cargo.toml b/Cargo.toml index 8e6e514b287..60740704f8c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,7 +48,7 @@ dunce = "1.0.4" either = "1.13.0" esl01-renderdag = "0.3.0" futures = "0.3.30" -git2 = "0.18.3" +git2 = "0.19.0" gix = { version = "0.63.0", default-features = false, features = [ "index", "max-performance-safe", diff --git a/cli/tests/test_git_push.rs b/cli/tests/test_git_push.rs index 8126e24442e..7e3cfe75f18 100644 --- a/cli/tests/test_git_push.rs +++ b/cli/tests/test_git_push.rs @@ -1235,6 +1235,8 @@ fn test_git_push_moved_sideways_untracked() { } #[test] +// TODO: This test fails with libgit2 v1.8.1 on Windows. +#[cfg(not(target_os = "windows"))] fn test_git_push_to_remote_named_git() { let (test_env, workspace_root) = set_up(); let git_repo = { diff --git a/lib/src/git.rs b/lib/src/git.rs index d7066a22f73..f4030a7ca2d 100644 --- a/lib/src/git.rs +++ b/lib/src/git.rs @@ -1265,7 +1265,12 @@ pub fn fetch( tracing::debug!("remote.prune"); remote.prune(None)?; tracing::debug!("remote.update_tips"); - remote.update_tips(None, false, git2::AutotagOption::Unspecified, None)?; + remote.update_tips( + None, + git2::RemoteUpdateFlags::empty(), + git2::AutotagOption::Unspecified, + None, + )?; // TODO: We could make it optional to get the default branch since we only care // about it on clone. let mut default_branch = None; From 91f3d5ef2cd6c812ae4307f37800086fd14976d1 Mon Sep 17 00:00:00 2001 From: Ilya Grigoriev Date: Sun, 28 Jul 2024 21:37:10 -0700 Subject: [PATCH 2/5] test_git_push: make tests work on newer libgit2-s This should make it unnecessary to disable a test in #4080. --- cli/tests/test_git_push.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cli/tests/test_git_push.rs b/cli/tests/test_git_push.rs index 8126e24442e..c923cd5b182 100644 --- a/cli/tests/test_git_push.rs +++ b/cli/tests/test_git_push.rs @@ -38,7 +38,8 @@ fn set_up() -> (TestEnvironment, PathBuf) { "git", "clone", "--config-toml=git.auto-local-branch=true", - origin_git_repo_path.to_str().unwrap(), + // Git and libgit2 > 1.8 do not allow backslashes in remote names + &origin_git_repo_path.to_str().unwrap().replace("\\", "/"), "local", ], ); From 7b97d969ed62d8c0c4ff8ae6c41cc442dc6fb700 Mon Sep 17 00:00:00 2001 From: Ilya Grigoriev Date: Tue, 30 Jul 2024 20:49:03 -0700 Subject: [PATCH 3/5] backout of commit 91f3d5ef2cd6c812ae4307f37800086fd14976d1 --- cli/tests/test_git_push.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cli/tests/test_git_push.rs b/cli/tests/test_git_push.rs index c923cd5b182..8126e24442e 100644 --- a/cli/tests/test_git_push.rs +++ b/cli/tests/test_git_push.rs @@ -38,8 +38,7 @@ fn set_up() -> (TestEnvironment, PathBuf) { "git", "clone", "--config-toml=git.auto-local-branch=true", - // Git and libgit2 > 1.8 do not allow backslashes in remote names - &origin_git_repo_path.to_str().unwrap().replace("\\", "/"), + origin_git_repo_path.to_str().unwrap(), "local", ], ); From 8e033def2fe9e593d60112bc2544c74636e0eb55 Mon Sep 17 00:00:00 2001 From: Ilya Grigoriev Date: Tue, 30 Jul 2024 20:36:51 -0700 Subject: [PATCH 4/5] path_slash --- Cargo.lock | 7 +++++++ cli/Cargo.toml | 1 + cli/src/commands/git/clone.rs | 16 +++++++++++----- cli/tests/common/mod.rs | 6 ++++-- 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1dbaf1d9568..cf10983eb6d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1879,6 +1879,7 @@ dependencies = [ "maplit", "minus", "once_cell", + "path-slash", "pest", "pest_derive", "pollster", @@ -2341,6 +2342,12 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" +[[package]] +name = "path-slash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e91099d4268b0e11973f036e885d652fb0b21fedcf69738c627f94db6a44f42" + [[package]] name = "pathdiff" version = "0.2.1" diff --git a/cli/Cargo.toml b/cli/Cargo.toml index ffb41e2997e..86f8daca561 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -74,6 +74,7 @@ jj-lib = { workspace = true } maplit = { workspace = true } minus = { workspace = true } once_cell = { workspace = true } +path-slash = "0.2.1" pest = { workspace = true } pest_derive = { workspace = true } pollster = { workspace = true } diff --git a/cli/src/commands/git/clone.rs b/cli/src/commands/git/clone.rs index b7cfdf81011..018b5d33917 100644 --- a/cli/src/commands/git/clone.rs +++ b/cli/src/commands/git/clone.rs @@ -20,6 +20,7 @@ use jj_lib::git::{self, GitFetchError, GitFetchStats}; use jj_lib::repo::Repo; use jj_lib::str_util::StringPattern; use jj_lib::workspace::Workspace; +use path_slash::PathBufExt; use crate::cli_util::{CommandHelper, WorkspaceCommandHelper}; use crate::command_error::{cli_error, user_error, user_error_with_message, CommandError}; @@ -53,12 +54,17 @@ fn absolute_git_source(cwd: &Path, source: &str) -> String { // be tedious to copy the exact git (or libgit2) behavior, we simply assume a // source containing ':' is a URL, SSH remote, or absolute path with Windows // drive letter. + // TODO: Match "This syntax is only recognized if there are no slashes before the first colon" from https://git-scm.com/docs/git-clone#_git_urls + // TODO: Pass paths like `c:\qq` to path_slash if !source.contains(':') && Path::new(source).exists() { - // It's less likely that cwd isn't utf-8, so just fall back to original source. - cwd.join(source) - .into_os_string() - .into_string() - .unwrap_or_else(|_| source.to_owned()) + // TODO: This won't work for Windows UNC path or (less importantly) if the + // original source is a non-UTF Windows path. For Windows UNC paths, we + // could use dunce, though see also https://gitlab.com/kornelski/dunce/-/issues/7 + cwd.join(source).to_slash().map_or_else( + // It's less likely that cwd isn't utf-8, so just fall back to original source. + || source.to_owned(), + |s| s.to_string(), + ) } else { source.to_owned() } diff --git a/cli/tests/common/mod.rs b/cli/tests/common/mod.rs index 72f4eb5a51e..ce42e03c3a3 100644 --- a/cli/tests/common/mod.rs +++ b/cli/tests/common/mod.rs @@ -17,6 +17,7 @@ use std::collections::HashMap; use std::path::{Path, PathBuf}; use itertools::Itertools as _; +use path_slash::PathBufExt; use regex::{Captures, Regex}; use tempfile::TempDir; @@ -320,8 +321,9 @@ impl TestEnvironment { pub fn normalize_output(&self, text: &str) -> String { let text = text.replace("jj.exe", "jj"); let regex = Regex::new(&format!( - r"{}(\S+)", - regex::escape(&self.env_root.display().to_string()) + r"({}|{})(\S+)", + regex::escape(&self.env_root.display().to_string()), + regex::escape(&self.env_root.to_slash_lossy()) )) .unwrap(); regex From 450a6a526520b7a0611e13488294ebbf7aaef54f Mon Sep 17 00:00:00 2001 From: Ilya Grigoriev Date: Tue, 30 Jul 2024 21:05:36 -0700 Subject: [PATCH 5/5] looks_like_a_path_to_git --- cli/src/commands/git/clone.rs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/cli/src/commands/git/clone.rs b/cli/src/commands/git/clone.rs index 018b5d33917..ffb5fbc3ca8 100644 --- a/cli/src/commands/git/clone.rs +++ b/cli/src/commands/git/clone.rs @@ -48,15 +48,24 @@ pub struct GitCloneArgs { colocate: bool, } +fn looks_like_a_path_to_git(source: &str) -> bool { + source.chars().nth(1) == Some(':') || // Looks like a Windows C:... path + // Match Git's behavior, the URL syntax [is only recognized if there are no + // slashes before the first + // colon](https://git-scm.com/docs/git-clone#_git_urls) + !source + .split_once("/") + .map_or(source, |(first, _)| first) + .contains(":") +} + fn absolute_git_source(cwd: &Path, source: &str) -> String { // Git appears to turn URL-like source to absolute path if local git directory // exits, and fails because '$PWD/https' is unsupported protocol. Since it would // be tedious to copy the exact git (or libgit2) behavior, we simply assume a // source containing ':' is a URL, SSH remote, or absolute path with Windows // drive letter. - // TODO: Match "This syntax is only recognized if there are no slashes before the first colon" from https://git-scm.com/docs/git-clone#_git_urls - // TODO: Pass paths like `c:\qq` to path_slash - if !source.contains(':') && Path::new(source).exists() { + if looks_like_a_path_to_git(source) && Path::new(source).exists() { // TODO: This won't work for Windows UNC path or (less importantly) if the // original source is a non-UTF Windows path. For Windows UNC paths, we // could use dunce, though see also https://gitlab.com/kornelski/dunce/-/issues/7