altsem / gitu

A TUI Git client inspired by Magit
MIT License
1.74k stars 89 forks source link

Stash commands and status #37

Closed altsem closed 5 months ago

altsem commented 6 months ago

We're missing the stash list on the status page, as well as stash commands.

Start with save / pop / apply. Some of these commands open up a prompt, like zz prompts you to name the stash. zp will also prompt which stash to pop (default to 0, or the marked one).

image

golden-expiriensu commented 5 months ago

Hey @altsem! I wanted to help on this one, but I have encountered an issue with retrieving list of stashes via git2 lib which the project uses. As far as I understand, for git stash list git2 it uses cmd_list function which under the hood uses git_stash_foreach function (with printing callback), which takes &mut Repository in rust implementation. The issue is that your interface for creating screen accepts Rc<Repository>, so changing it to something mutable and breaking existing code does not sound good for me. Do you have any ideas on workarounds for that?

altsem commented 5 months ago

I think keeping the reference to Repository immutable is not a requirement, but makes the code easier to reason about. If it needs to be a Rc<RefCell> (I think?), it's not a huge deal.

Had a peek over at Gitoxide and it seems there's no support for it, else it could have been a good segue into starting to use that.

I found the git cli function here. It seems to be referencing refs/stash, perhaps there's a way to list these with more nitty-gritty git2 commands?

altsem commented 5 months ago

@golden-expiriensu I played around with it a bit, stole some code from the log fn. It lists a lot more than just what git stash would, not sure why. But the stash entries are indeed found in there.

#[test]
fn stash_list() {
    let repo = Repository::open(".").unwrap();
    let mut revwalk = repo.revwalk().unwrap();
    revwalk.push_ref("refs/stash").unwrap();
    dbg!(revwalk
        .flat_map(|maybe_oid| maybe_oid.and_then(|oid| repo.find_commit(oid)))
        .map(|commit| commit.summary().unwrap().to_string())
        .collect::<Vec<_>>());

    todo!();
}

Again, if git_stash_foreach proves to be really simple to use, we could compromise and get rid of the immutable reference to Repository!

golden-expiriensu commented 5 months ago

I believe I found another way, under the hood git uses reflog to find changes of ref/stash file, so I think git reflog stash is a solution