support push to origin (#266)

* use  vendored ssl
This commit is contained in:
Stephan Dilly 2020-09-02 02:08:41 +02:00 committed by GitHub
parent 08f6735d99
commit 7d1e3643b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 237 additions and 12 deletions

View File

@ -11,8 +11,8 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2

View File

@ -15,7 +15,6 @@ jobs:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
rust: [nightly, stable]
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.rust == 'nightly' }}
@ -54,14 +53,13 @@ jobs:
build-linux-musl:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@master
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
profile: minimal
target: x86_64-unknown-linux-musl
- name: Setup MUSL
run: |
sudo apt-get -qq install musl-tools
@ -73,6 +71,9 @@ jobs:
run: |
make build-linux-musl-release
./target/x86_64-unknown-linux-musl/release/gitui --version
- name: Test
run: |
make test-linux-musl
rustfmt:
name: Rustfmt

47
Cargo.lock generated
View File

@ -414,6 +414,8 @@ dependencies = [
"libc",
"libgit2-sys",
"log",
"openssl-probe",
"openssl-sys",
"url",
]
@ -552,10 +554,26 @@ checksum = "0100ae90655025134424939f1f60e27e879460d451dff6afedde4f8226cbebfc"
dependencies = [
"cc",
"libc",
"libssh2-sys",
"libz-sys",
"openssl-sys",
"pkg-config",
]
[[package]]
name = "libssh2-sys"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca46220853ba1c512fc82826d0834d87b06bcd3c2a42241b7de72f3d2fe17056"
dependencies = [
"cc",
"libc",
"libz-sys",
"openssl-sys",
"pkg-config",
"vcpkg",
]
[[package]]
name = "libz-sys"
version = "1.1.0"
@ -785,6 +803,35 @@ version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ab52be62400ca80aa00285d25253d7f7c437b7375c4de678f5405d3afe82ca5"
[[package]]
name = "openssl-probe"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
[[package]]
name = "openssl-src"
version = "111.10.2+1.1.1g"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a287fdb22e32b5b60624d4a5a7a02dbe82777f730ec0dbc42a0554326fef5a70"
dependencies = [
"cc",
]
[[package]]
name = "openssl-sys"
version = "0.9.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a842db4709b604f0fe5d1170ae3565899be2ad3d9cbc72dedc789ac0511f78de"
dependencies = [
"autocfg",
"cc",
"libc",
"openssl-src",
"pkg-config",
"vcpkg",
]
[[package]]
name = "parking_lot"
version = "0.10.2"

View File

@ -31,6 +31,9 @@ build-linux-musl-debug:
build-linux-musl-release:
cargo build --release --target=x86_64-unknown-linux-musl --no-default-features
test-linux-musl:
cargo test --workspace --target=x86_64-unknown-linux-musl --no-default-features
test:
cargo test --workspace

View File

@ -59,4 +59,5 @@
commit_amend: ( code: Char('A'), modifiers: ( bits: 0,),),
copy: ( code: Char('y'), modifiers: ( bits: 0,),),
create_branch: ( code: Char('b'), modifiers: ( bits: 0,),),
push: ( code: Char('p'), modifiers: ( bits: 0,),),
)

View File

@ -13,7 +13,7 @@ keywords = ["git"]
[dependencies]
scopetime = { path = "../scopetime", version = "0.1" }
git2 = { version = "0.13.10", default-features = false }
git2 = { version = "0.13", features = ["vendored-openssl"] }
rayon-core = "1.8"
crossbeam-channel = "0.4"
log = "0.4"

View File

@ -32,6 +32,11 @@ impl BranchName {
self.fetch(current_head)
}
///
pub fn last(&self) -> Option<String> {
self.last_result.as_ref().map(|last| last.1.clone())
}
fn fetch(&mut self, head: Head) -> Result<String> {
let name = sync::get_branch_name(self.repo_path.as_str())?;
self.last_result = Some((head, name.clone()));

View File

@ -10,6 +10,7 @@ mod hooks;
mod hunks;
mod ignore;
mod logwalker;
mod remotes;
mod reset;
mod stash;
pub mod status;
@ -29,6 +30,9 @@ pub use hooks::{hooks_commit_msg, hooks_post_commit, HookResult};
pub use hunks::{reset_hunk, stage_hunk, unstage_hunk};
pub use ignore::add_to_ignore;
pub use logwalker::LogWalker;
pub use remotes::{
fetch_origin, get_remotes, push_origin, remote_push_master,
};
pub use reset::{reset_stage, reset_workdir};
pub use stash::{get_stashes, stash_apply, stash_drop, stash_save};
pub use tags::{get_tags, CommitTags, Tags};

View File

@ -0,0 +1,103 @@
//!
use crate::{error::Result, sync::utils};
use git2::{Cred, FetchOptions, PushOptions, RemoteCallbacks};
use scopetime::scope_time;
///
pub fn get_remotes(repo_path: &str) -> Result<Vec<String>> {
scope_time!("get_remotes");
let repo = utils::repo(repo_path)?;
let remotes = repo.remotes()?;
let remotes: Vec<String> =
remotes.iter().filter_map(|s| s).map(String::from).collect();
Ok(remotes)
}
///
pub fn remote_push_master(repo_path: &str) -> Result<()> {
scope_time!("remote_push_master");
let repo = utils::repo(repo_path)?;
let mut remote = repo.find_remote("origin")?;
remote.push(&["refs/heads/master"], None)?;
Ok(())
}
///
pub fn fetch_origin(repo_path: &str, branch: &str) -> Result<usize> {
scope_time!("remote_fetch_master");
let repo = utils::repo(repo_path)?;
let mut remote = repo.find_remote("origin")?;
let mut options = FetchOptions::new();
options.remote_callbacks(remote_callbacks());
remote.fetch(&[branch], Some(&mut options), None)?;
Ok(remote.stats().received_bytes())
}
///
pub fn push_origin(repo_path: &str, branch: &str) -> Result<()> {
scope_time!("push_origin");
let repo = utils::repo(repo_path)?;
let mut remote = repo.find_remote("origin")?;
let mut options = PushOptions::new();
options.remote_callbacks(remote_callbacks());
remote.push(&[branch], Some(&mut options))?;
Ok(())
}
fn remote_callbacks<'a>() -> RemoteCallbacks<'a> {
let mut callbacks = RemoteCallbacks::new();
callbacks.credentials(|url, username_from_url, allowed_types| {
log::debug!(
"creds: '{}' {:?} ({:?})",
url,
username_from_url,
allowed_types
);
Cred::ssh_key_from_agent(
username_from_url.expect("username not found"),
)
});
callbacks
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sync::tests::debug_cmd_print;
use tempfile::TempDir;
#[test]
fn test_smoke() {
let td = TempDir::new().unwrap();
debug_cmd_print(
td.path().as_os_str().to_str().unwrap(),
"git clone https://github.com/extrawurst/brewdump.git",
);
let repo_path = td.path().join("brewdump");
let repo_path = repo_path.as_os_str().to_str().unwrap();
let remotes = get_remotes(repo_path).unwrap();
assert_eq!(remotes, vec![String::from("origin")]);
fetch_origin(repo_path, "master").unwrap();
}
}

View File

@ -256,7 +256,7 @@ impl App {
let msg =
format!("failed to launch editor:\n{}", e);
log::error!("{}", msg.as_str());
self.msg.show_msg(msg.as_str())?;
self.msg.show_error(msg.as_str())?;
}
self.requires_redraw.set(true);
@ -454,7 +454,12 @@ impl App {
flags.insert(NeedsUpdate::COMMANDS);
}
InternalEvent::ShowErrorMsg(msg) => {
self.msg.show_msg(msg.as_str())?;
self.msg.show_error(msg.as_str())?;
flags
.insert(NeedsUpdate::ALL | NeedsUpdate::COMMANDS);
}
InternalEvent::ShowInfoMsg(msg) => {
self.msg.show_info(msg.as_str())?;
flags
.insert(NeedsUpdate::ALL | NeedsUpdate::COMMANDS);
}

View File

@ -20,7 +20,7 @@ pub fn copy_string(_string: String) -> Result<()> {
}
#[cfg(feature = "clipboard")]
pub fn is_supported() -> bool {
pub const fn is_supported() -> bool {
true
}

View File

@ -64,6 +64,11 @@ impl ChangesComponent {
Ok(())
}
///
pub fn branch_name(&self) -> Option<String> {
self.branch_name.last()
}
///
pub fn set_items(&mut self, list: &[StatusItem]) -> Result<()> {
self.files.update(list)?;

View File

@ -14,6 +14,7 @@ use tui::{
use ui::style::SharedTheme;
pub struct MsgComponent {
title: String,
msg: String,
visible: bool,
theme: SharedTheme,
@ -39,9 +40,7 @@ impl DrawableComponent for MsgComponent {
Paragraph::new(txt.iter())
.block(
Block::default()
.title(&strings::msg_title_error(
&self.key_config,
))
.title(self.title.as_str())
.title_style(self.theme.text_danger())
.borders(Borders::ALL)
.border_type(BorderType::Thick),
@ -104,14 +103,26 @@ impl MsgComponent {
key_config: SharedKeyConfig,
) -> Self {
Self {
title: String::new(),
msg: String::new(),
visible: false,
theme,
key_config,
}
}
///
pub fn show_msg(&mut self, msg: &str) -> Result<()> {
pub fn show_error(&mut self, msg: &str) -> Result<()> {
self.title = strings::msg_title_error(&self.key_config);
self.msg = msg.to_string();
self.show()?;
Ok(())
}
///
pub fn show_info(&mut self, msg: &str) -> Result<()> {
self.title = strings::msg_title_info(&self.key_config);
self.msg = msg.to_string();
self.show()?;

View File

@ -60,6 +60,7 @@ pub struct KeyConfig {
pub commit_amend: KeyEvent,
pub copy: KeyEvent,
pub create_branch: KeyEvent,
pub push: KeyEvent,
}
#[rustfmt::skip]
@ -109,6 +110,7 @@ impl Default for KeyConfig {
commit_amend: KeyEvent { code: KeyCode::Char('a'), modifiers: KeyModifiers::CONTROL},
copy: KeyEvent { code: KeyCode::Char('y'), modifiers: KeyModifiers::empty()},
create_branch: KeyEvent { code: KeyCode::Char('b'), modifiers: KeyModifiers::empty()},
push: KeyEvent { code: KeyCode::Char('p'), modifiers: KeyModifiers::empty()},
}
}
}

View File

@ -39,6 +39,8 @@ pub enum InternalEvent {
///
ShowErrorMsg(String),
///
ShowInfoMsg(String),
///
Update(NeedsUpdate),
/// open commit msg input
OpenCommit,

View File

@ -40,6 +40,9 @@ pub fn msg_opening_editor(_key_config: &SharedKeyConfig) -> String {
pub fn msg_title_error(_key_config: &SharedKeyConfig) -> String {
"Error".to_string()
}
pub fn msg_title_info(_key_config: &SharedKeyConfig) -> String {
"Info".to_string()
}
pub fn commit_title(_key_config: &SharedKeyConfig) -> String {
"Commit".to_string()
}
@ -596,4 +599,11 @@ pub mod commands {
CMD_GROUP_GENERAL,
)
}
pub fn status_push(key_config: &SharedKeyConfig) -> CommandText {
CommandText::new(
format!("Push [{}]", get_hint(key_config.push),),
"push to origin",
CMD_GROUP_GENERAL,
)
}
}

View File

@ -323,6 +323,24 @@ impl Status {
true
}
}
fn push(&self) {
if let Some(branch) = self.index_wd.branch_name() {
let branch = format!("refs/heads/{}", branch);
if let Err(e) = sync::push_origin(CWD, branch.as_str()) {
self.queue.borrow_mut().push_back(
InternalEvent::ShowErrorMsg(format!(
"push failed:\n{}",
e
)),
);
} else {
self.queue.borrow_mut().push_back(
InternalEvent::ShowInfoMsg("pushed".to_string()),
);
}
}
}
}
impl Component for Status {
@ -369,6 +387,11 @@ impl Component for Status {
true,
true,
));
out.push(CommandInfo::new(
strings::commands::status_push(&self.key_config),
self.index_wd.branch_name().is_some(),
true,
));
out.push(
CommandInfo::new(
@ -451,6 +474,9 @@ impl Component for Status {
.borrow_mut()
.push_back(InternalEvent::CreateBranch);
Ok(true)
} else if k == self.key_config.push {
self.push();
Ok(true)
} else {
Ok(false)
};