mirror of
https://github.com/gitbutlerapp/gitbutler.git
synced 2024-12-18 14:31:30 +03:00
Merge pull request #5045 from gitbutlerapp/Stacking-handle-upstream-commits
Stacking: fix upstream handling
This commit is contained in:
commit
91f0a916ce
@ -471,7 +471,8 @@ fn stack_series(
|
|||||||
check_commit: &IsCommitIntegrated,
|
check_commit: &IsCommitIntegrated,
|
||||||
) -> Result<Vec<PatchSeries>> {
|
) -> Result<Vec<PatchSeries>> {
|
||||||
let mut api_series: Vec<PatchSeries> = vec![];
|
let mut api_series: Vec<PatchSeries> = vec![];
|
||||||
for series in branch.list_series(ctx)? {
|
let stack_series = branch.list_series(ctx)?;
|
||||||
|
for series in stack_series.clone() {
|
||||||
let upstream_reference = default_target.push_remote_name.as_ref().and_then(|remote| {
|
let upstream_reference = default_target.push_remote_name.as_ref().and_then(|remote| {
|
||||||
if series.head.pushed(remote.as_str(), ctx).ok()? {
|
if series.head.pushed(remote.as_str(), ctx).ok()? {
|
||||||
series.head.remote_reference(remote.as_str()).ok()
|
series.head.remote_reference(remote.as_str()).ok()
|
||||||
@ -480,21 +481,41 @@ fn stack_series(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
let mut patches: Vec<VirtualBranchCommit> = vec![];
|
let mut patches: Vec<VirtualBranchCommit> = vec![];
|
||||||
for patch in series.local_commits {
|
for patch in series.clone().local_commits {
|
||||||
let commit = commit_by_oid_or_change_id(&patch, ctx, branch.head, default_target)?;
|
let commit = commit_by_oid_or_change_id(&patch, ctx, branch.head, default_target)?;
|
||||||
let is_integrated = check_commit.is_integrated(&commit)?;
|
let is_integrated = check_commit.is_integrated(&commit)?;
|
||||||
// TODO: correctly determine if commit is remote
|
let vcommit = commit_to_vbranch_commit(
|
||||||
let vcommit =
|
ctx,
|
||||||
commit_to_vbranch_commit(ctx, branch, &commit, is_integrated, false, None)?;
|
branch,
|
||||||
|
&commit,
|
||||||
|
is_integrated,
|
||||||
|
series.remote(&patch),
|
||||||
|
None,
|
||||||
|
)?;
|
||||||
patches.push(vcommit);
|
patches.push(vcommit);
|
||||||
}
|
}
|
||||||
patches.reverse();
|
patches.reverse();
|
||||||
|
let mut upstream_patches = vec![];
|
||||||
|
for patch in series.upstream_only(&stack_series) {
|
||||||
|
let commit = commit_by_oid_or_change_id(&patch, ctx, branch.head, default_target)?;
|
||||||
|
let is_integrated = check_commit.is_integrated(&commit)?;
|
||||||
|
let vcommit = commit_to_vbranch_commit(
|
||||||
|
ctx,
|
||||||
|
branch,
|
||||||
|
&commit,
|
||||||
|
is_integrated,
|
||||||
|
true, // per definition
|
||||||
|
None,
|
||||||
|
)?;
|
||||||
|
upstream_patches.push(vcommit);
|
||||||
|
}
|
||||||
|
upstream_patches.reverse();
|
||||||
api_series.push(PatchSeries {
|
api_series.push(PatchSeries {
|
||||||
name: series.head.name,
|
name: series.head.name,
|
||||||
description: series.head.description,
|
description: series.head.description,
|
||||||
upstream_reference,
|
upstream_reference,
|
||||||
patches,
|
patches,
|
||||||
upstream_patches: vec![],
|
upstream_patches,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
api_series.reverse();
|
api_series.reverse();
|
||||||
|
@ -45,7 +45,7 @@ impl PatchReference {
|
|||||||
|
|
||||||
/// Returns `true` if the reference is pushed to the provided remote
|
/// Returns `true` if the reference is pushed to the provided remote
|
||||||
pub fn pushed(&self, remote: &str, ctx: &CommandContext) -> Result<bool> {
|
pub fn pushed(&self, remote: &str, ctx: &CommandContext) -> Result<bool> {
|
||||||
let remote_ref = self.remote_reference(remote)?;
|
let remote_ref = self.remote_reference(remote)?; // todo: this should probably just return false
|
||||||
Ok(ctx.repository().find_reference(&remote_ref).is_ok())
|
Ok(ctx.repository().find_reference(&remote_ref).is_ok())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,3 +20,25 @@ pub struct Series {
|
|||||||
/// Topologically ordered, the first entry is the newest in the series.
|
/// Topologically ordered, the first entry is the newest in the series.
|
||||||
pub remote_commits: Vec<CommitOrChangeId>,
|
pub remote_commits: Vec<CommitOrChangeId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Series {
|
||||||
|
/// Returns `true` if the provided patch is part of the remote commits in this series (i.e. has been pushed).
|
||||||
|
pub fn remote(&self, patch: &CommitOrChangeId) -> bool {
|
||||||
|
self.remote_commits.contains(patch)
|
||||||
|
}
|
||||||
|
/// Returns a list of patches that are only in the upstream (remote) and not in the local commits,
|
||||||
|
/// as determined by the commit ID or change ID.
|
||||||
|
/// This comparison is peformed against the full stack of series.
|
||||||
|
pub fn upstream_only(&self, stack_series: &[Series]) -> Vec<CommitOrChangeId> {
|
||||||
|
let mut upstream_only = vec![];
|
||||||
|
for commit in &self.remote_commits {
|
||||||
|
if !stack_series
|
||||||
|
.iter()
|
||||||
|
.any(|s| s.local_commits.contains(commit))
|
||||||
|
{
|
||||||
|
upstream_only.push(commit.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
upstream_only
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -386,10 +386,28 @@ impl Stack for Branch {
|
|||||||
None => CommitOrChangeId::CommitId(c.id().to_string()),
|
None => CommitOrChangeId::CommitId(c.id().to_string()),
|
||||||
})
|
})
|
||||||
.collect_vec();
|
.collect_vec();
|
||||||
|
|
||||||
|
let mut remote_patches: Vec<CommitOrChangeId> = vec![];
|
||||||
|
if let Some(remote_name) = default_target.push_remote_name.as_ref() {
|
||||||
|
if head.pushed(remote_name, ctx).unwrap_or_default() {
|
||||||
|
let head_commit = repo
|
||||||
|
.find_reference(&head.remote_reference(remote_name)?)?
|
||||||
|
.peel_to_commit()?;
|
||||||
|
let merge_base = repo.merge_base(head_commit.id(), default_target.sha)?;
|
||||||
|
repo.log(head_commit.id(), LogUntil::Commit(merge_base))?
|
||||||
|
.iter()
|
||||||
|
.rev()
|
||||||
|
.map(|c| match c.change_id() {
|
||||||
|
Some(change_id) => CommitOrChangeId::ChangeId(change_id.to_string()),
|
||||||
|
None => CommitOrChangeId::CommitId(c.id().to_string()),
|
||||||
|
})
|
||||||
|
.for_each(|c| remote_patches.push(c));
|
||||||
|
}
|
||||||
|
};
|
||||||
all_series.push(Series {
|
all_series.push(Series {
|
||||||
head: head.clone(),
|
head: head.clone(),
|
||||||
local_commits: local_patches,
|
local_commits: local_patches,
|
||||||
remote_commits: vec![], // TODO
|
remote_commits: remote_patches,
|
||||||
});
|
});
|
||||||
previous_head = head_commit;
|
previous_head = head_commit;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user