Skip to content

Commit 3c5e86e

Browse files
author
Stephan Dilly
authored
stashing support (#70)
1 parent 5936757 commit 3c5e86e

File tree

18 files changed

+1281
-544
lines changed

18 files changed

+1281
-544
lines changed

assets/stashing.drawio

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<mxfile host="app.diagrams.net" modified="2020-05-19T12:41:55.023Z" agent="5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1 Safari/605.1.15" etag="G_7kN2nuUboj_f0S3bPh" version="13.1.3" type="device" pages="2"><diagram id="hAseTAaTBIQ-p2lVXsqS" name="Page-1">7Vlbk5owFP41zLQPO0NAUB+97LZ92Je1l+coEegGQiGu2l/f3CBEcNzuiLK2L5p8JyTk+87JSYLlzpLdpxxm0SMJELYcO9hZ7txynOHIZ78c2EvAc8cSCPM4kBDQwCL+jRRoK3QTB6gwGlJCMI0zE1yRNEUramAwz8nWbLYm2Bw1gyFqAIsVxE30RxzQSKIjZ6jxzygOo3Jk4Kv5JbBsrGZSRDAg2xrk3lvuLCeEylKymyHMuSt5kc89HLFWL5ajlL7mgadvOMToyV8+foFPYA6+D4Y/71QvLxBv1ITVy9J9yUBONmmAeCe25U63UUzRIoMrbt0yyRkW0QSzGmBF1R3KKdodfU9QzZ55DSIJovmeNSkfsBVhpceo6lbT7/oKi2rUOyUIleRh1bVmhRUUMX9BktNDkoBJ0qhJUuV4BkmgK5LcBkkLCummaFDFJk1NPgqak2c0I5jkDElJylpO1zHGBxDEcZiy6oqRhBg+5RTGLFYnypDEQcCHaRXAlKgDDVocddAmQVcKDNoUKKI4DXuqwZqkdKFeCpxDEO+kIK0LR1eC+E1B4AvqqRgdBIQzvnJEjPu3cA/8Yc+yWylar1gamiy1pDe31ZM6S2+guVO69fx2KMK18xto24f5mJNdZDBl5ZCKmUtsWQIiC7IzhMLZ2MvDtgwzu+ilpvV8aZ9BYO+0wBfNl6C5h4yYdJbDurO/xgmSpcmGRoxiURbapjDpIqtitKa9C8K2jf5lo7C5zZxkGd6boVhTwv+14Ufc6UqyPGHGPFzCD+wFbSlia+kjL3IKbe72d2uYxGwQ8XhCUlII3o0mhbg84A3sbKfH1UHtHV5TeGzeHBWH8KpW8uAJJhgy52X+Yh6fucfoO9UWVG1Lqd/UjaO7kXRXljL3lGZJd2UWzs9q0v05DES1HgIcFR7PDToMDFiGAofU+sVBMyC4UYUEN9aCgltEWHC8DAwO2gKpzU0GyGvYq0wVcTpkPB40uiXQTNt7jXs1WAZRZRrUTCqWtBQ1Gyw0HtaGP1RVVCtp66DpcKpdwzPfU27qYKm7+vEBeI2lbp6T7HYV8MBpBbyLKtA8Qj/EGIFbzfavuda7bAgMWwVonhBvVIDqMvp6Coz+b4pPZYrrq1R2fLZLlAO+z0BadWFyfG2pvL/O2bgzzlo+PnnTneXNBW/Cye1NSnO4euY7x9v05bfK0p0rt1yzNGRh/+G/o0nb+nJhUVo/r8lrrVvdjTqnv69ddDPqvOsPbGe5MASXujC01BlZ22qnY/f+Dw==</diagram><diagram id="o9nFayAMEWxc9pClOnIG" name="Page-2">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</diagram></mxfile>

asyncgit/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@ mod diff;
88
mod error;
99
mod revlog;
1010
mod status;
11+
mod status2;
1112
pub mod sync;
1213

1314
pub use crate::{
1415
diff::{AsyncDiff, DiffParams},
1516
revlog::AsyncLog,
1617
status::AsyncStatus,
18+
status2::{AsyncStatus2, StatusParams},
1719
sync::{
1820
diff::{DiffLine, DiffLineType, FileDiff},
1921
status::{StatusItem, StatusItemType},

asyncgit/src/status2.rs

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
use crate::{
2+
current_tick, error::Result, hash, sync, AsyncNotification,
3+
StatusItem, CWD,
4+
};
5+
use crossbeam_channel::Sender;
6+
use log::trace;
7+
use std::{
8+
hash::Hash,
9+
sync::{
10+
atomic::{AtomicUsize, Ordering},
11+
Arc, Mutex,
12+
},
13+
};
14+
use sync::status::StatusType;
15+
16+
#[derive(Default, Hash, Clone)]
17+
pub struct Status2 {
18+
pub items: Vec<StatusItem>,
19+
}
20+
21+
///
22+
#[derive(Default, Hash, Clone, PartialEq)]
23+
pub struct StatusParams {
24+
tick: u64,
25+
status_type: StatusType,
26+
include_untracked: bool,
27+
}
28+
29+
impl StatusParams {
30+
///
31+
pub fn new(
32+
status_type: StatusType,
33+
include_untracked: bool,
34+
) -> Self {
35+
Self {
36+
tick: current_tick(),
37+
status_type,
38+
include_untracked,
39+
}
40+
}
41+
}
42+
43+
struct Request<R, A>(R, Option<A>);
44+
45+
///TODO: merge functionality with AsyncStatus
46+
pub struct AsyncStatus2 {
47+
current: Arc<Mutex<Request<u64, Status2>>>,
48+
last: Arc<Mutex<Status2>>,
49+
sender: Sender<AsyncNotification>,
50+
pending: Arc<AtomicUsize>,
51+
}
52+
53+
impl AsyncStatus2 {
54+
///
55+
pub fn new(sender: Sender<AsyncNotification>) -> Self {
56+
Self {
57+
current: Arc::new(Mutex::new(Request(0, None))),
58+
last: Arc::new(Mutex::new(Status2::default())),
59+
sender,
60+
pending: Arc::new(AtomicUsize::new(0)),
61+
}
62+
}
63+
64+
///
65+
pub fn last(&mut self) -> Result<Status2> {
66+
let last = self.last.lock()?;
67+
Ok(last.clone())
68+
}
69+
70+
///
71+
pub fn is_pending(&self) -> bool {
72+
self.pending.load(Ordering::Relaxed) > 0
73+
}
74+
75+
///
76+
pub fn fetch(
77+
&mut self,
78+
params: StatusParams,
79+
) -> Result<Option<Status2>> {
80+
let hash_request = hash(&params);
81+
82+
trace!("request: [hash: {}]", hash_request);
83+
84+
{
85+
let mut current = self.current.lock()?;
86+
87+
if current.0 == hash_request {
88+
return Ok(current.1.clone());
89+
}
90+
91+
current.0 = hash_request;
92+
current.1 = None;
93+
}
94+
95+
let arc_current = Arc::clone(&self.current);
96+
let arc_last = Arc::clone(&self.last);
97+
let sender = self.sender.clone();
98+
let arc_pending = Arc::clone(&self.pending);
99+
let status_type = params.status_type;
100+
let include_untracked = params.include_untracked;
101+
rayon_core::spawn(move || {
102+
arc_pending.fetch_add(1, Ordering::Relaxed);
103+
104+
Self::fetch_helper(
105+
status_type,
106+
include_untracked,
107+
hash_request,
108+
arc_current,
109+
arc_last,
110+
)
111+
.expect("failed to fetch status");
112+
113+
arc_pending.fetch_sub(1, Ordering::Relaxed);
114+
115+
sender
116+
.send(AsyncNotification::Status)
117+
.expect("error sending status");
118+
});
119+
120+
Ok(None)
121+
}
122+
123+
fn fetch_helper(
124+
status_type: StatusType,
125+
include_untracked: bool,
126+
hash_request: u64,
127+
arc_current: Arc<Mutex<Request<u64, Status2>>>,
128+
arc_last: Arc<Mutex<Status2>>,
129+
) -> Result<()> {
130+
let res = Self::get_status(status_type, include_untracked)?;
131+
trace!("status fetched: {}", hash(&res));
132+
133+
{
134+
let mut current = arc_current.lock()?;
135+
if current.0 == hash_request {
136+
current.1 = Some(res.clone());
137+
}
138+
}
139+
140+
{
141+
let mut last = arc_last.lock()?;
142+
*last = res;
143+
}
144+
145+
Ok(())
146+
}
147+
148+
fn get_status(
149+
status_type: StatusType,
150+
include_untracked: bool,
151+
) -> Result<Status2> {
152+
Ok(Status2 {
153+
items: sync::status::get_status_new(
154+
CWD,
155+
status_type,
156+
include_untracked,
157+
)?,
158+
})
159+
}
160+
}

asyncgit/src/sync/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ mod hooks;
66
mod hunks;
77
mod logwalker;
88
mod reset;
9+
mod stash;
910
pub mod status;
1011
mod tags;
1112
pub mod utils;
@@ -17,6 +18,7 @@ pub use logwalker::LogWalker;
1718
pub use reset::{
1819
reset_stage, reset_workdir_file, reset_workdir_folder,
1920
};
21+
pub use stash::stash_save;
2022
pub use tags::{get_tags, Tags};
2123
pub use utils::{
2224
commit, stage_add_all, stage_add_file, stage_addremoved,

asyncgit/src/sync/stash.rs

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
#![allow(dead_code)]
2+
use super::utils::repo;
3+
use crate::error::Result;
4+
use git2::{Oid, StashFlags};
5+
use scopetime::scope_time;
6+
7+
///
8+
pub struct StashItem {
9+
pub msg: String,
10+
index: usize,
11+
id: Oid,
12+
}
13+
14+
///
15+
pub struct StashItems(Vec<StashItem>);
16+
17+
///
18+
pub fn get_stashes(repo_path: &str) -> Result<StashItems> {
19+
scope_time!("get_stashes");
20+
21+
let mut repo = repo(repo_path)?;
22+
23+
let mut list = Vec::new();
24+
25+
repo.stash_foreach(|index, msg, id| {
26+
list.push(StashItem {
27+
msg: msg.to_string(),
28+
index,
29+
id: *id,
30+
});
31+
true
32+
})?;
33+
34+
Ok(StashItems(list))
35+
}
36+
37+
///
38+
pub fn stash_save(
39+
repo_path: &str,
40+
message: Option<&str>,
41+
include_untracked: bool,
42+
keep_index: bool,
43+
) -> Result<()> {
44+
scope_time!("stash_save");
45+
46+
let mut repo = repo(repo_path)?;
47+
48+
let sig = repo.signature()?;
49+
50+
let mut options = StashFlags::DEFAULT;
51+
52+
if include_untracked {
53+
options.insert(StashFlags::INCLUDE_UNTRACKED);
54+
}
55+
if keep_index {
56+
options.insert(StashFlags::KEEP_INDEX)
57+
}
58+
59+
repo.stash_save2(&sig, message, Some(options))?;
60+
61+
Ok(())
62+
}
63+
64+
#[cfg(test)]
65+
mod tests {
66+
use super::*;
67+
use crate::sync::tests::{get_statuses, repo_init};
68+
use std::{fs::File, io::Write};
69+
70+
#[test]
71+
fn test_smoke() {
72+
let (_td, repo) = repo_init().unwrap();
73+
let root = repo.path().parent().unwrap();
74+
let repo_path = root.as_os_str().to_str().unwrap();
75+
76+
assert_eq!(
77+
stash_save(repo_path, None, true, false).is_ok(),
78+
false
79+
);
80+
81+
assert_eq!(
82+
get_stashes(repo_path).unwrap().0.is_empty(),
83+
true
84+
);
85+
}
86+
87+
#[test]
88+
fn test_stashing() -> Result<()> {
89+
let (_td, repo) = repo_init().unwrap();
90+
let root = repo.path().parent().unwrap();
91+
let repo_path = root.as_os_str().to_str().unwrap();
92+
93+
File::create(&root.join("foo.txt"))?
94+
.write_all(b"test\nfoo")?;
95+
96+
assert_eq!(get_statuses(repo_path), (1, 0));
97+
98+
stash_save(repo_path, None, true, false)?;
99+
100+
assert_eq!(get_statuses(repo_path), (0, 0));
101+
102+
Ok(())
103+
}
104+
105+
#[test]
106+
fn test_stashes() -> Result<()> {
107+
let (_td, repo) = repo_init().unwrap();
108+
let root = repo.path().parent().unwrap();
109+
let repo_path = root.as_os_str().to_str().unwrap();
110+
111+
File::create(&root.join("foo.txt"))?
112+
.write_all(b"test\nfoo")?;
113+
114+
stash_save(repo_path, Some("foo"), true, false)?;
115+
116+
let res = get_stashes(repo_path)?;
117+
118+
assert_eq!(res.0.len(), 1);
119+
assert_eq!(res.0[0].msg, "On master: foo");
120+
assert_eq!(res.0[0].index, 0);
121+
122+
Ok(())
123+
}
124+
}

asyncgit/src/sync/status.rs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,36 +46,54 @@ pub struct StatusItem {
4646
}
4747

4848
///
49-
#[derive(Copy, Clone)]
49+
#[derive(Copy, Clone, Hash, PartialEq)]
5050
pub enum StatusType {
5151
///
5252
WorkingDir,
5353
///
5454
Stage,
55+
///
56+
Both,
57+
}
58+
59+
impl Default for StatusType {
60+
fn default() -> Self {
61+
StatusType::WorkingDir
62+
}
5563
}
5664

5765
impl Into<StatusShow> for StatusType {
5866
fn into(self) -> StatusShow {
5967
match self {
6068
StatusType::WorkingDir => StatusShow::Workdir,
6169
StatusType::Stage => StatusShow::Index,
70+
StatusType::Both => StatusShow::IndexAndWorkdir,
6271
}
6372
}
6473
}
6574

66-
///
75+
/// TODO: migrate
6776
pub fn get_status(
6877
repo_path: &str,
6978
status_type: StatusType,
7079
) -> Result<Vec<StatusItem>> {
71-
scope_time!("get_index");
80+
get_status_new(repo_path, status_type, true)
81+
}
82+
83+
/// TODO: migrate
84+
pub fn get_status_new(
85+
repo_path: &str,
86+
status_type: StatusType,
87+
include_untracked: bool,
88+
) -> Result<Vec<StatusItem>> {
89+
scope_time!("get_status");
7290

7391
let repo = utils::repo(repo_path)?;
7492

7593
let statuses = repo.statuses(Some(
7694
StatusOptions::default()
7795
.show(status_type.into())
78-
.include_untracked(true)
96+
.include_untracked(include_untracked)
7997
.renames_head_to_index(true)
8098
.recurse_untracked_dirs(true),
8199
))?;

0 commit comments

Comments
 (0)