Peter Yates
Peter Yates

Reputation: 25

Adding and committing a new file with git2go

I am currently struggling to stage and commit a file to a git repository in memory (i.e. without writing a file to disk, adding and committing it)

Here's a shortened version of my code; it almost works

package main

import (
    "fmt"
    "gopkg.in/libgit2/git2go.v25"
    "time"
)

func main() {

    sig := &git.Signature{
        Name:  "Some Person",
        Email: "[email protected]",
        When:  time.Now(),
    }

    repo, err := git.OpenRepository("./repo")
    check(err)
    defer repo.Free()

    content := []byte("hello world")

    index, err := repo.Index()
    check(err)

    oid, err := repo.CreateBlobFromBuffer(content)
    check(err)

    ie := git.IndexEntry{
        Mode: git.FilemodeBlob,
        Id:   oid,
        Path: "documents/document_9.md",
    }

    err = index.Add(&ie)
    check(err)

    treeId, err := index.WriteTree()
    check(err)

    tree, err := repo.LookupTree(treeId)
    check(err)

    index.Write()

    currentBranch, err := repo.Head()
    check(err)

    currentTip, err := repo.LookupCommit(currentBranch.Target())
    check(err)

    commitId, err := repo.CreateCommit("HEAD", sig, sig, "A new commit", tree, currentTip)

    check(err)
    fmt.Println(commitId)

}

func check(err error) {
    if err != nil {
        panic(err)
    }
}

However, when I run it and look in ./repo, something's not quite right. As you can see from git status, the new document_9.md file is marked as being deleted (i.e. git knows about it but it's not present)

❯ git status
On branch master
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)

        deleted:    documents/document_9.md

Looking at the log, it's confirmed that the commit actually worked:

❯ git log --patch
commit a609b43e6a3f7da7d0589971ab0f64f3f432e76c
Author: Some Person <[email protected]>
Date:   Thu Mar 23 19:43:56 2017 +0000

    a new commit

diff --git a/documents/document_9.md b/documents/document_9.md
new file mode 100644
index 0000000..95d09f2
--- /dev/null
+++ b/documents/document_9.md
@@ -0,0 +1 @@
+hello world
\ No newline at end of file

commit 668762279b51483c05dbdedcf3c599a1b41c203b
Author: Original Committer <[email protected]>
Date:   Thu Mar 23 19:42:52 2017 +0000

    First commit

diff --git a/documents/docment_1.md b/documents/docment_1.md
new file mode 100644
index 0000000..2965834
--- /dev/null
+++ b/documents/docment_1.md
@@ -0,0 +1 @@
+# Hello World

I believe that I'm missing a step. Somehow I need to ensure that my commit is 'synced' with the filesystem. I thought that (based on the documentation), this was achieved by index.Write() and index.WriteTree(), but I can't get it to work.

Any nudge in the right direction would be much appreciated.

Upvotes: 1

Views: 430

Answers (1)

Jason Haslam
Jason Haslam

Reputation: 2897

If you want the working directory to match the state of the new HEAD commit then you need to check it out (e.g. with the go equivalent of git_checkout_head).

git_index_write_tree writes a tree object to the object database and git_index_write writes the in-memory representation of the index out to disk. Neither affect the working directory.

Upvotes: 1

Related Questions