Skip to content

Commit

Permalink
(For CI -- test that the parent PR works)
Browse files Browse the repository at this point in the history
  • Loading branch information
ilyagr committed Jul 31, 2024
3 parents ce29824 + 9a6e5d4 + ee5ccdf commit 8b7fcce
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 33 deletions.
16 changes: 12 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ dunce = "1.0.4"
either = "1.13.0"
esl01-renderdag = "0.3.0"
futures = "0.3.30"
git2 = { version = "0.18.3", features = [
git2 = { version = "0.19.0", features = [
# Do *not* disable this feature even if you'd like dynamic linking. Instead,
# set the environment variable `LIBGIT2_NO_VENDOR=1` if dynamic linking must
# be used (this will override the Cargo feature), and allow static linking
Expand Down Expand Up @@ -76,6 +76,7 @@ maplit = "1.0.2"
minus = { version = "5.6.1", features = ["dynamic_output", "search"] }
num_cpus = "1.16.0"
once_cell = "1.19.0"
path-slash = "0.2.1"
pest = "2.7.11"
pest_derive = "2.7.11"
pollster = "0.3.0"
Expand Down
1 change: 1 addition & 0 deletions cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ jj-lib = { workspace = true }
maplit = { workspace = true }
minus = { workspace = true }
once_cell = { workspace = true }
path-slash = { workspace = true }
pest = { workspace = true }
pest_derive = { workspace = true }
pollster = { workspace = true }
Expand Down
21 changes: 2 additions & 19 deletions cli/src/commands/git/clone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use std::io::Write;
use std::path::{Path, PathBuf};
use std::{fs, io};

use jj_lib::git::{self, GitFetchError, GitFetchStats};
use jj_lib::git::{self, sanitize_git_url_if_path, GitFetchError, GitFetchStats};
use jj_lib::repo::Repo;
use jj_lib::str_util::StringPattern;
use jj_lib::workspace::Workspace;
Expand Down Expand Up @@ -47,23 +47,6 @@ pub struct GitCloneArgs {
colocate: bool,
}

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.
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())
} else {
source.to_owned()
}
}

fn clone_destination_for_source(source: &str) -> Option<&str> {
let destination = source.strip_suffix(".git").unwrap_or(source);
let destination = destination.strip_suffix('/').unwrap_or(destination);
Expand All @@ -89,7 +72,7 @@ pub fn cmd_git_clone(
return Err(cli_error("--at-op is not respected"));
}
let remote_name = "origin";
let source = absolute_git_source(command.cwd(), &args.source);
let source = sanitize_git_url_if_path(command.cwd(), &args.source);
let wc_path_str = args
.destination
.as_deref()
Expand Down
8 changes: 6 additions & 2 deletions cli/src/commands/git/remote/add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use jj_lib::git;
use jj_lib::git::{self, sanitize_git_url_if_path};
use jj_lib::repo::Repo;

use crate::cli_util::CommandHelper;
Expand All @@ -37,6 +37,10 @@ pub fn cmd_git_remote_add(
let workspace_command = command.workspace_helper(ui)?;
let repo = workspace_command.repo();
let git_repo = get_git_repo(repo.store())?;
git::add_remote(&git_repo, &args.remote, &args.url)?;
git::add_remote(
&git_repo,
&args.remote,
&sanitize_git_url_if_path(command.cwd(), &args.url),
)?;
Ok(())
}
2 changes: 1 addition & 1 deletion cli/src/commands/git/remote/set_url.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,6 @@ pub fn cmd_git_remote_set_url(
let workspace_command = command.workspace_helper(ui)?;
let repo = workspace_command.repo();
let git_repo = get_git_repo(repo.store())?;
git::set_remote_url(&git_repo, &args.remote, &args.url)?;
git::set_remote_url(&git_repo, &args.remote, &args.url, command.cwd())?;
Ok(())
}
8 changes: 5 additions & 3 deletions cli/tests/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -320,13 +321,14 @@ 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
.replace_all(&text, |caps: &Captures| {
format!("$TEST_ENV{}", caps[1].replace('\\', "/"))
format!("$TEST_ENV{}", caps[2].replace('\\', "/"))
})
.to_string()
}
Expand Down
1 change: 1 addition & 0 deletions lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ itertools = { workspace = true }
jj-lib-proc-macros = { workspace = true }
maplit = { workspace = true }
once_cell = { workspace = true }
path-slash = { workspace = true }
pest = { workspace = true }
pest_derive = { workspace = true }
pollster = { workspace = true }
Expand Down
44 changes: 41 additions & 3 deletions lib/src/git.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ use std::borrow::Cow;
use std::collections::{BTreeMap, HashMap, HashSet};
use std::default::Default;
use std::io::Read;
use std::path::PathBuf;
use std::path::{Path, PathBuf};
use std::{fmt, str};

use git2::Oid;
use itertools::Itertools;
use path_slash::PathBufExt;
use tempfile::NamedTempFile;
use thiserror::Error;

Expand Down Expand Up @@ -1143,10 +1144,42 @@ pub fn rename_remote(
Ok(())
}

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(":")
}

pub fn sanitize_git_url_if_path(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.
if looks_like_a_path_to_git(source) {
// 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()
}
}

pub fn set_remote_url(
git_repo: &git2::Repository,
remote_name: &str,
new_remote_url: &str,
cwd: &Path,
) -> Result<(), GitRemoteManagementError> {
if remote_name == REMOTE_NAME_FOR_LOCAL_GIT_REPO {
return Err(GitRemoteManagementError::RemoteReservedForLocalGitRepo);
Expand All @@ -1164,7 +1197,7 @@ pub fn set_remote_url(
})?;

git_repo
.remote_set_url(remote_name, new_remote_url)
.remote_set_url(remote_name, &sanitize_git_url_if_path(cwd, new_remote_url))
.map_err(GitRemoteManagementError::InternalGitError)?;
Ok(())
}
Expand Down Expand Up @@ -1265,7 +1298,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;
Expand Down

0 comments on commit 8b7fcce

Please sign in to comment.