Closed NYBACHOK closed 9 months ago
I believe it would be roughly equivalent to do a fetch (https://github.com/rust-lang/git2-rs/blob/master/examples/fetch.rs roughly shows the API) and then a rebase using Repository::rebase
(https://github.com/rust-lang/git2-rs/blob/dc63db55c5d605e6ac0516d48c3fff4e34b709f8/src/rebase.rs#L337-L441 shows some rough examples of that API).
@ehuss Thanks. Later I add my result with merging and rebase. I think it will be helpful for others.
My final code. In one moment, I was said to replace rebase with merge
pub fn repo_merge_upstream( &self )
-> Result< (), GitErrors >
{
//---------------- ADD REMOTE AND FETCH -------------\\
const UPSTREAM_NAME : &str = "upstream";
let mut fetch_options = FetchOptions::new();
fetch_options.remote_callbacks( Self::callback_with_credentials_get( &self.options.auth ) );
self.repository.remote( UPSTREAM_NAME, self.options.upstream_url.0.as_str() )
.map_err( GitErrors::Git2Error )?
.fetch( &[ &self.options.default_branch ], Some( &mut fetch_options ), None)
.map_err( GitErrors::Git2Error )?;
//--------------- MERGE ------------\\
let merge_from_name = format!( "{UPSTREAM_NAME}/{}", self.options.default_branch );
let merge_from = self.repository.find_branch( &merge_from_name, BranchType::Remote )
.map_err( GitErrors::Git2Error )?;
let merge_into = self.repository.find_branch(&self.options.default_branch , BranchType::Local )
.map_err( GitErrors::Git2Error )?;
let merge_from_commit = self.repository.reference_to_annotated_commit( merge_from.get() )
.map_err( GitErrors::Git2Error )?;
let (merge_analysis, _merge_preference) = self.repository.merge_analysis(&[ &merge_from_commit] )
.map_err( GitErrors::Git2Error )?;
if merge_analysis.is_up_to_date()
{
return Err( GitErrors::UpToDate )
}
let mut checkout_opt = CheckoutBuilder::default();
checkout_opt.update_index( true );
checkout_opt.use_theirs( true );
checkout_opt.allow_conflicts( true );
self.repository.merge( &[ &merge_from_commit ], None, Some( &mut checkout_opt ) )
.map_err( GitErrors::Git2Error )?;
let mut index = self.repository.index()
.map_err( GitErrors::Git2Error )?;
index.add_all( [ "*" ].iter(), IndexAddOption::DEFAULT, None )
.map_err( GitErrors::Git2Error )?;
index.write()
.map_err( GitErrors::Git2Error )?;
let tree_id = index.write_tree()
.map_err( GitErrors::Git2Error )?;
if index.has_conflicts()
{
return Err( GitErrors::MergeConflicts )
}
let signature = Signature::now( "example", "example@example.com" ).map_err( GitErrors::Git2Error )?;
let commit_msg = format!( "Merge branch '{UPSTREAM_NAME}/{}'", self.options.default_branch );
let _commit_oid = self.repository.commit
(
Some( "HEAD" ), // Use HEAD to automatically point to the current branch
&signature, // Commit author
&signature, // Commit committer
&commit_msg, // Commit message
&self.repository.find_tree( tree_id ).map_err( GitErrors::Git2Error )?, // The tree to commit
&[ &merge_into.get().peel_to_commit().map_err( GitErrors::Git2Error )? ],
).map_err( GitErrors::Git2Error )?;
dbg!( &_commit_oid );
// --------------- REBASE ----------- \\
// let upstream_master_oid = self.repository.refname_to_id(&format!("refs/remotes/{UPSTREAM_NAME}/{}", self.options.default_branch))
// .map_err( GitErrors::Git2Error )?;
// dbg!(&upstream_master_oid);
//
// let upstream_master_commit = self.repository.find_annotated_commit(upstream_master_oid)
// .map_err( GitErrors::Git2Error )?;
//
// let self_master_oid = self.repository.refname_to_id(&format!("refs/remotes/origin/{}", self.options.default_branch))
// .map_err( GitErrors::Git2Error )?;
// dbg!(&self_master_oid);
//
// let self_master_commit = self.repository.find_annotated_commit(upstream_master_oid)
// .map_err( GitErrors::Git2Error )?;
//
// let mut rebase_options = RebaseOptions::default();
// rebase_options.inmemory( false );
//
// let mut rebase = self.repository.rebase(
// None,
// Some( &upstream_master_commit ),
// Some(&self_master_commit),
// Some(&mut rebase_options)
// )
// .map_err( GitErrors::Git2Error )?;
//
// for reb in rebase.by_ref()
// {
// reb.map_err( GitErrors::Git2Error )?;
// }
//
// rebase.finish( None)
// .map_err( GitErrors::Git2Error )?;
//------------------ PUSH TO REMOTE ----------------\\
let mut remote = self.repository.find_remote( "origin" )
.map_err( GitErrors::Git2Error )?;
let mut push_options = PushOptions::new();
push_options.remote_callbacks(Self::callback_with_credentials_get( &self.options.auth ) );
// "+refs/heads/master:refs/heads/master" for force push
let refspec : &[&str] = &["refs/heads/master:refs/heads/master" ];
remote.push(refspec, Some( &mut push_options ) )
.map_err( GitErrors::Git2Error )?;
Ok( () )
}
Hi, I need to write method similar for
git pull upstream master --rebase
and after that to push changes to remote