Skip to content

Commit 4dee9ec

Browse files
committed
Ensure that init always fetches base from upstream
1 parent e5b8282 commit 4dee9ec

File tree

2 files changed

+15
-18
lines changed

2 files changed

+15
-18
lines changed

rust/patchable/src/main.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -174,12 +174,6 @@ pub enum Error {
174174

175175
#[snafu(display("failed to open product repository at {path:?}"))]
176176
OpenProductRepo { source: git2::Error, path: PathBuf },
177-
#[snafu(display("failed to find base commit {commit:?} in repository {repo}"))]
178-
FindBaseCommit {
179-
source: git2::Error,
180-
repo: error::RepoPath,
181-
commit: String,
182-
},
183177
#[snafu(display("failed to find head commit in repository {repo}"))]
184178
FindHeadCommit {
185179
source: git2::Error,
@@ -245,7 +239,7 @@ fn main() -> Result<()> {
245239
.in_scope(|| repo::ensure_bare_repo(&product_repo_root))
246240
.context(OpenProductRepoForCheckoutSnafu)?;
247241

248-
let base_commit = repo::resolve_commitish_or_fetch(
242+
let base_commit = repo::resolve_and_fetch_commitish(
249243
&product_repo,
250244
&config.base.to_string(),
251245
&config.upstream,
@@ -341,7 +335,7 @@ fn main() -> Result<()> {
341335
// --base can be a reference, but patchable.toml should always have a resolved commit id,
342336
// so that it cannot be changed under our feet (without us knowing so, anyway...).
343337
tracing::info!(?base, "resolving base commit-ish");
344-
let base_commit = repo::resolve_commitish_or_fetch(&product_repo, &base, &upstream)
338+
let base_commit = repo::resolve_and_fetch_commitish(&product_repo, &base, &upstream)
345339
.context(FetchBaseCommitSnafu)?;
346340
tracing::info!(?base, base.commit = ?base_commit, "resolved base commit");
347341

rust/patchable/src/repo.rs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -105,24 +105,29 @@ pub fn ensure_bare_repo(path: &Path) -> Result<Repository> {
105105
}
106106
}
107107

108-
/// Try to resolve `commitish` locally. If it doesn't exist, try to fetch it from `upstream_url`.
108+
/// Try to resolve and fetch `commitish` from `upstream_url`.
109+
///
110+
/// As an optimization, it can skip fetching if `commitish` is a literal commit ID that exists locally.
109111
///
110112
/// Returns the resolved commit ID.
111113
#[tracing::instrument(skip(repo))]
112-
pub fn resolve_commitish_or_fetch(
114+
pub fn resolve_and_fetch_commitish(
113115
repo: &Repository,
114116
commitish: &str,
115117
upstream_url: &str,
116118
) -> Result<Oid> {
117-
let commit = match repo.revparse_single(commitish) {
119+
let oid = Oid::from_str(commitish);
120+
let commitish_is_oid = oid.is_ok();
121+
let local_commit = oid.and_then(|oid| repo.find_commit(oid));
122+
let commit = match local_commit {
118123
Ok(commit_obj) => {
119-
tracing::info!("base commit exists, reusing");
124+
tracing::info!("literal commit exists locally, reusing");
120125
Ok(commit_obj)
121126
}
122-
Err(err) if err.code() == git2::ErrorCode::NotFound => {
127+
Err(err) if !commitish_is_oid || err.code() == git2::ErrorCode::NotFound => {
123128
tracing::info!(
124129
error = &err as &dyn std::error::Error,
125-
"base commit not found, fetching from upstream"
130+
"base commit not found locally, fetching from upstream"
126131
);
127132
repo.remote_anonymous(upstream_url)
128133
.context(CreateRemoteSnafu {
@@ -147,17 +152,15 @@ pub fn resolve_commitish_or_fetch(
147152
tracing::info!("fetched base commit");
148153
// FETCH_HEAD is written by Remote::fetch to be the last reference fetched
149154
repo.revparse_single("FETCH_HEAD")
155+
.and_then(|obj| obj.peel_to_commit())
150156
}
151157
Err(err) => Err(err),
152158
}
153159
.context(FindCommitSnafu {
154160
repo,
155161
commit: commitish,
156162
})?;
157-
Ok(commit
158-
.peel_to_commit()
159-
.context(FindCommitSnafu { repo, commit })?
160-
.id())
163+
Ok(commit.id())
161164
}
162165

163166
/// Ensure that the worktree at `worktree_root` exists and is checked out at `branch`.

0 commit comments

Comments
 (0)