mirror of
https://github.com/gitbutlerapp/gitbutler.git
synced 2024-12-25 10:33:21 +03:00
prefer rebase when merging upstream into vbranch
This commit is contained in:
parent
789181fdbe
commit
4b4f6e210f
@ -947,7 +947,7 @@ fn test_add_new_hunk_to_the_end() -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_merge_vbranch_upstream_clean() -> Result<()> {
|
fn test_merge_vbranch_upstream_clean_rebase() -> Result<()> {
|
||||||
let suite = Suite::default();
|
let suite = Suite::default();
|
||||||
let Case {
|
let Case {
|
||||||
project_repository,
|
project_repository,
|
||||||
@ -1064,15 +1064,10 @@ fn test_merge_vbranch_upstream_clean() -> Result<()> {
|
|||||||
);
|
);
|
||||||
let contents = std::fs::read(std::path::Path::new(&project.path).join(file_path2))?;
|
let contents = std::fs::read(std::path::Path::new(&project.path).join(file_path2))?;
|
||||||
assert_eq!("file2\n", String::from_utf8(contents)?);
|
assert_eq!("file2\n", String::from_utf8(contents)?);
|
||||||
assert_eq!(branch1.files.len(), 0);
|
assert_eq!(branch1.files.len(), 1);
|
||||||
assert_eq!(branch1.commits.len(), 3);
|
assert_eq!(branch1.commits.len(), 2);
|
||||||
// assert_eq!(branch1.upstream.as_ref().unwrap().commits.len(), 0);
|
// assert_eq!(branch1.upstream.as_ref().unwrap().commits.len(), 0);
|
||||||
|
|
||||||
// make sure the last commit was signed
|
|
||||||
let last_id = &branch1.commits[0].id;
|
|
||||||
let last_commit = project_repository.git_repository.find_commit(*last_id)?;
|
|
||||||
assert!(last_commit.raw_header().unwrap().contains("SSH SIGNATURE"));
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ use std::os::unix::prelude::*;
|
|||||||
|
|
||||||
use anyhow::{bail, Context, Result};
|
use anyhow::{bail, Context, Result};
|
||||||
use diffy::{apply_bytes, Patch};
|
use diffy::{apply_bytes, Patch};
|
||||||
use git2_hooks::HookResult;
|
use git2_hooks::{HookResult, PrepareCommitMsgSource};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
@ -1430,20 +1430,88 @@ pub fn merge_virtual_branch_upstream(
|
|||||||
Some(upstream_commit.id()),
|
Some(upstream_commit.id()),
|
||||||
)?;
|
)?;
|
||||||
} else {
|
} else {
|
||||||
// get the merge tree oid from writing the index out
|
|
||||||
let merge_tree_oid = merge_index
|
let merge_tree_oid = merge_index
|
||||||
.write_tree_to(repo)
|
.write_tree_to(repo)
|
||||||
.context("failed to write tree")?;
|
.context("failed to write tree")?;
|
||||||
|
let merge_tree = repo
|
||||||
|
.find_tree(merge_tree_oid)
|
||||||
|
.context("failed to find merge tree")?;
|
||||||
|
let branch_writer =
|
||||||
|
branch::Writer::new(gb_repository).context("failed to create writer")?;
|
||||||
|
|
||||||
|
if *project_repository.project().ok_with_force_push {
|
||||||
|
// attempt a rebase
|
||||||
|
let (_, committer) = project_repository.git_signatures(user)?;
|
||||||
|
let mut rebase_options = git2::RebaseOptions::new();
|
||||||
|
rebase_options.quiet(true);
|
||||||
|
rebase_options.inmemory(true);
|
||||||
|
let mut rebase = repo
|
||||||
|
.rebase(
|
||||||
|
Some(branch.head),
|
||||||
|
Some(upstream_commit.id()),
|
||||||
|
None,
|
||||||
|
Some(&mut rebase_options),
|
||||||
|
)
|
||||||
|
.context("failed to rebase")?;
|
||||||
|
|
||||||
|
let mut rebase_success = true;
|
||||||
|
// check to see if these commits have already been pushed
|
||||||
|
let mut last_rebase_head = upstream_commit.id();
|
||||||
|
while rebase.next().is_some() {
|
||||||
|
let index = rebase
|
||||||
|
.inmemory_index()
|
||||||
|
.context("failed to get inmemory index")?;
|
||||||
|
if index.has_conflicts() {
|
||||||
|
rebase_success = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Ok(commit_id) = rebase.commit(None, &committer.clone().into(), None) {
|
||||||
|
last_rebase_head = commit_id.into();
|
||||||
|
} else {
|
||||||
|
rebase_success = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if rebase_success {
|
||||||
|
// rebase worked out, rewrite the branch head
|
||||||
|
rebase.finish(None).context("failed to finish rebase")?;
|
||||||
|
|
||||||
|
project_repository
|
||||||
|
.git_repository
|
||||||
|
.checkout_tree(&merge_tree)
|
||||||
|
.force()
|
||||||
|
.checkout()
|
||||||
|
.context("failed to checkout tree")?;
|
||||||
|
|
||||||
|
branch.head = last_rebase_head;
|
||||||
|
branch.tree = merge_tree_oid;
|
||||||
|
branch_writer.write(&mut branch)?;
|
||||||
|
super::integration::update_gitbutler_integration(
|
||||||
|
gb_repository,
|
||||||
|
project_repository,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
rebase.abort().context("failed to abort rebase")?;
|
||||||
|
}
|
||||||
|
|
||||||
let head_commit = repo
|
let head_commit = repo
|
||||||
.find_commit(branch.head)
|
.find_commit(branch.head)
|
||||||
.context("failed to find head commit")?;
|
.context("failed to find head commit")?;
|
||||||
let merge_tree = repo
|
|
||||||
.find_tree(merge_tree_oid)
|
|
||||||
.context("failed to find merge tree")?;
|
|
||||||
let new_branch_head = project_repository.commit(
|
let new_branch_head = project_repository.commit(
|
||||||
user,
|
user,
|
||||||
"merged from upstream",
|
format!(
|
||||||
|
"Merged {}/{} into {}",
|
||||||
|
upstream_branch.remote(),
|
||||||
|
upstream_branch.branch(),
|
||||||
|
branch.name
|
||||||
|
)
|
||||||
|
.as_str(),
|
||||||
&merge_tree,
|
&merge_tree,
|
||||||
&[&head_commit, &upstream_commit],
|
&[&head_commit, &upstream_commit],
|
||||||
signing_key,
|
signing_key,
|
||||||
@ -1456,8 +1524,6 @@ pub fn merge_virtual_branch_upstream(
|
|||||||
.context("failed to checkout tree")?;
|
.context("failed to checkout tree")?;
|
||||||
|
|
||||||
// write the branch data
|
// write the branch data
|
||||||
let branch_writer =
|
|
||||||
branch::Writer::new(gb_repository).context("failed to create writer")?;
|
|
||||||
branch.head = new_branch_head;
|
branch.head = new_branch_head;
|
||||||
branch.tree = merge_tree_oid;
|
branch.tree = merge_tree_oid;
|
||||||
branch_writer.write(&mut branch)?;
|
branch_writer.write(&mut branch)?;
|
||||||
|
Loading…
Reference in New Issue
Block a user