How can I do `git add some-file.rs`, `git commit -m "message`, `git push` with git2 crate on a bare repo

I am using code from this issue add and commit issues · Issue #561 · rust-lang/git2-rs · GitHub
Code works fine for repo that already have some commits.

Can anyone please provide a simple working code for these 3 actions.

git add and git commit is invalid in a bare repo, you're probably misunderstading something here.

as to the git push, you need a Remote, then call Remote::push().

// use an already registered remote:
let mut remote = repo.find_remote("origin").unwrap();

// add a new remote
/*
let mut remote = repo.remote("origin", "https://github.com/abc/xyz").unwrap();
*/

// push branch name "main" to the remote, use default settings (i.e. no proxy etc.)
remote.push(&["refs/heads/main"], None).unwrap();

Sorry, I meant empty repo.
mkdir my-repo && cd my-repo
git init
git remote add some-remote-origin

after all these commands
I want to add, commit and push

in git terms, the staging area is called "index", many commands such as add, rm actually just edit the index database.

to add a file:

	// open the index database of the given repository
	// the repo can't be bare, must have a worktree
	let mut index = repo.index().unwrap();
	// suppose you made some change to "hello.txt", add it to the index
	index.add_path(Path::new("hello.txt")).unwrap();
	// the modified in-memory index need to flush back to disk
	index.write().unwrap();

if you do git status now, you'll see something like this:

Y:\workspace>git status
On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   hello.txt

to commit a change, in git term you write the index database into the repo's object database, create a new tree with old tree as parent.

	// follows previous snippet, index is updated by `add_path()`
	// write the whole tree from the index to the repo object store
	// returns the object id you can use to lookup the actual tree object
	let new_tree_oid = index.write_tree().unwrap();
	// this is our new tree, i.e. the root directory of the new commit
	let new_tree = repo.find_tree(tree_oid).unwrap();

	// either use the configured author signature
	let author = repo.signature().unwrap();
	// or use an alternative signature. commiter and author need not be the same
	/*
	let author = Signature::now("nick", "nick@example.com");
	*/

	// for simple commit, use current head as parent
	// you need more than one parent if the commit is a merge
	let head = repo.head().unwrap();
	let parent = repo.find_commit(head.target().unwrap()).unwrap();
	repo
		.commit(
			Some("HEAD"),
			&author,
			&author,
			"this is a commit message",
			&new_tree,
			&[&parent],
		)
		.unwrap();
1 Like

Thank you for the help.