Skip to content

wrong lifetime for Repository Index #897

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
seanaye opened this issue Nov 13, 2022 · 4 comments · Fixed by #922
Closed

wrong lifetime for Repository Index #897

seanaye opened this issue Nov 13, 2022 · 4 comments · Fixed by #922

Comments

@seanaye
Copy link

seanaye commented Nov 13, 2022

I am following the example from the docs for replicating git add *

my code:

    let repo = match get_marble_store() {
        Ok(r) => Ok(r),
        Err(_) => match Repository::open(get_path(None)) {
            Ok(r) => Ok(r),
            Err(e) => Err(e),
        },
    };

    let mut index = repo?.index()?;
    index.add_all(["*"].iter(), git2::IndexAddOption::DEFAULT, None)?;

    index.write()?;
    return Ok(());

When I run this I get cannot index add all. This operation is not allowed against bare repositories. This repo is not a bare repo though.
in .git/config bare=false.

I have tried using a repo created with git init as well as with git2-rs

    let mut opts = RepositoryInitOptions::new();
    opts.no_reinit(true).mkdir(true).mkpath(true).bare(false);
    return Repository::init_opts(path, &opts);
@ehuss
Copy link
Contributor

ehuss commented Nov 13, 2022

Can you show a complete example? For example, something like this:

use git2::*;
use std::error::Error;
use std::path::Path;

fn main() -> Result<(), Box<dyn Error>> {
    let repo_path = Path::new("myrepo");
    if repo_path.exists() {
        std::fs::remove_dir_all(&repo_path)?;
    }
    let mut opts = RepositoryInitOptions::new();
    opts.no_reinit(true).mkdir(true).mkpath(true).bare(false);
    let repo = Repository::init_opts(&repo_path, &opts)?;
    std::fs::write("myrepo/somefile.txt", "This is an example")?;
    let mut index = repo.index()?;
    index.add_all(["*"].iter(), git2::IndexAddOption::DEFAULT, None)?;
    index.write()?;
    Ok(())
}

The above works for me.

@seanaye
Copy link
Author

seanaye commented Nov 14, 2022

@ehuss thanks for looking at this

here a full sample of relevant code

use git2::{Repository, RepositoryInitOptions};
use std::fs::{write};
use std::path::PathBuf;

fn get_path(f: Option<&str>) -> PathBuf {
    let root = "/Users/seanaye/Desktop/marble/";
    return match f {
        None => PathBuf::from(root),
        Some(p) => [root, p].iter().collect(),
    };
}

fn get_marble_store() -> Result<git2::Repository, git2::Error> {
    let path = get_path(None);
    println!("{:?}", path);
    let mut opts = RepositoryInitOptions::new();
    opts.no_reinit(true).mkdir(true).mkpath(true).bare(false);
    return Repository::init_opts(path, &opts);
}


fn commit_changes() -> Result<(), git2::Error> {
    let repo = match get_marble_store() {
        Ok(r) => Ok(r),
        Err(_) => match Repository::open(get_path(None)) {
            Ok(r) => Ok(r),
            Err(e) => Err(e),
        },
    };

    let mut index = repo?.index()?;
    index.add_all(["*"].iter(), git2::IndexAddOption::DEFAULT, None)?;

    index.write()?;
    return Ok(());
}

#[tauri::command]
fn save(filename: &str, data: &str) {
    println!("{:?}", data);
    let filepath = get_path(Some(filename));
    let res = write(filepath, data);
    if res.is_err() {
        println!("{:?}", res.unwrap_err())
    }

    match commit_changes() {
        Ok(_) => println!("Changes saved!"),
        Err(e) => println!("Error saving changes {:?}", e)
    }

}

fn save is the "entrypoint"

@seanaye
Copy link
Author

seanaye commented Nov 14, 2022

I copied over your code and it is working, but I'm not sure why mine is giving an error. It could be there is something wrong with how i'm using the library but I don't think the error message should be This operation is not allowed against bare repositories

@ehuss
Copy link
Contributor

ehuss commented Nov 15, 2022

The Repository is being dropped in the line let mut index = repo?.index()?;. To work around that, place the repo in a local variable, as in:

    let repo = repo?;
    let mut index = repo.index()?;

Looking at the code, I think the bindings need to add some lifetimes to ensure an "owner" like the Repository outlives the things associated with it like the Index.

@ehuss ehuss changed the title cannot index add all. This operation is not allowed against bare repositories wrong lifetime for Repository Index Nov 15, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants