Fix tracking for git default branch

This commit is contained in:
Wildan M 2026-05-26 22:02:09 +07:00
parent 862b29d3d9
commit 67dccc053a
No known key found for this signature in database
GPG Key ID: 01AC53185C679C79
2 changed files with 77 additions and 35 deletions

View File

@ -253,19 +253,28 @@ pub fn fetch(recipe: &CookRecipe, check_source: bool, logger: &PtyOut) -> Result
}
}
(None, false) => {
let (_, remote_branch, remote_name, remote_url) =
get_git_remote_tracking(&source_dir)?;
// TODO: how to get default branch and compare it here?
if let Some(branch) = branch
&& branch != &remote_branch
let remote = get_git_remote_tracking(&source_dir)?;
if remote.local_branch != remote.tracking_branch {
false
} else if let Some(branch) = branch
&& branch != &remote.tracking_branch
{
false
} else if remote_name != "origin" || &remote_url != chop_dot_git(git) {
} else if branch.is_none() && remote.remote_branch != remote.tracking_branch
{
false
} else if remote.remote_name != "origin"
|| &remote.remote_url != chop_dot_git(git)
{
false
} else {
git_run_fetch(logger, &source_dir, git)?;
fetch_is_ran = true;
match get_git_fetch_rev(&source_dir, &remote_url, &remote_branch) {
match get_git_fetch_rev(
&source_dir,
&remote.remote_url,
&remote.remote_branch,
) {
Ok(fetch_rev) => fetch_rev == head_rev,
Err(e) => {
log_to_pty!(logger, "{}", e);

View File

@ -367,25 +367,45 @@ pub fn get_git_fetch_rev(dir: &PathBuf, remote_url: &str, remote_branch: &str) -
)())
}
/// (local_branch_name, remote_branch, remote_name, remote_url)
/// -> ("fix_stuff", "master", "origin", "https://gitlab.redox-os.org/willnode/redox")
pub fn get_git_remote_tracking(dir: &PathBuf) -> Result<(String, String, String, String)> {
let git_head = dir.join(".git/HEAD");
let git_config = dir.join(".git/config");
#[derive(Default, Debug)]
pub struct GitRemoteTracking {
/// from .git/HEAD
pub local_branch: String,
/// from .git/config -> [branch <local_branch_name>].merge
pub tracking_branch: String,
/// from .git/config -> [branch <local_branch_name>].remote (usually "origin")
pub remote_name: String,
/// from refs/remotes/<remote_name>/HEAD (the default branch on remote)
pub remote_branch: String,
/// from .git/config -> [remote <remote_branch_name>].url
pub remote_url: String,
}
let head_content = read_to_string(&git_head)?;
if !head_content.starts_with("ref: ") {
let sha = head_content.trim_end().to_string();
return Ok((sha, "".to_string(), "".to_string(), "".to_string()));
impl GitRemoteTracking {
pub fn detached(rev: String) -> Self {
Self {
local_branch: rev,
..Default::default()
}
}
}
let local_branch_path = head_content["ref: ".len()..].trim_end();
let local_branch_name = get_git_branch_name(local_branch_path)?;
pub fn get_git_remote_tracking(dir: &PathBuf) -> Result<GitRemoteTracking> {
let git_head = dir.join(".git/HEAD");
let local_branch = {
let head_content = read_to_string(&git_head)?;
if !head_content.starts_with("ref: ") {
let rev = head_content.trim_end().to_string();
return Ok(GitRemoteTracking::detached(rev));
}
let path = &head_content["ref: ".len()..];
get_git_branch_name(path.trim_end())?
};
let git_config = dir.join(".git/config");
let config_content = read_to_string(&git_config)?;
let branch_section = format!("[branch \"{}\"]", local_branch_name);
let branch_section = format!("[branch \"{}\"]", local_branch);
let mut remote_name: Option<String> = None;
let mut remote_branch: Option<String> = None;
let mut parsing_branch_section = false;
@ -413,13 +433,13 @@ pub fn get_git_remote_tracking(dir: &PathBuf) -> Result<(String, String, String,
}
}
let remote_name_str = remote_name.ok_or_else(wrap_other_err!(
let remote_name = remote_name.ok_or_else(wrap_other_err!(
"Branch {:?} is not tracking a remote",
local_branch_name
local_branch
))?;
let remote_branch_str = remote_branch.unwrap_or("".into());
let tracking_branch = remote_branch.unwrap_or("".into());
let remote_section = format!("[remote \"{}\"]", remote_name_str);
let remote_section = format!("[remote \"{}\"]", remote_name);
let mut remote_url: Option<String> = None;
let mut parsing_remote_section = false;
@ -445,17 +465,30 @@ pub fn get_git_remote_tracking(dir: &PathBuf) -> Result<(String, String, String,
}
}
let remote_url_str = remote_url.ok_or_else(wrap_other_err!(
let remote_url = remote_url.ok_or_else(wrap_other_err!(
"Could not find URL for remote {:?} in .git/config.",
remote_name_str
remote_name
))?;
Ok((
local_branch_name,
remote_branch_str,
remote_name_str,
remote_url_str,
))
let remote_branch = {
let head_path = format!(".git/refs/remotes/{remote_name}/HEAD");
let git_remote_head = dir.join(&head_path);
let head_content = read_to_string(&git_remote_head)?;
let path = head_content
.get("ref: ".len()..)
.ok_or_else(wrap_other_err!(
"Malformed content {:?} in {head_path}",
head_content
))?;
get_git_branch_name(path.trim_end())?
};
Ok(GitRemoteTracking {
local_branch,
tracking_branch,
remote_name,
remote_branch,
remote_url,
})
}
pub(crate) fn chop_dot_git(url: &str) -> &str {
@ -465,14 +498,14 @@ pub(crate) fn chop_dot_git(url: &str) -> &str {
url
}
fn get_git_branch_name(local_branch_path: &str) -> Result<String> {
fn get_git_branch_name(branch_path: &str) -> Result<String> {
// TODO: incorrectly handle branch with slashes
Ok(local_branch_path
Ok(branch_path
.split('/')
.last()
.ok_or_else(wrap_other_err!(
"Failed to parse branch name of {:?}",
local_branch_path
branch_path
))?
.to_string())
}