Добавление и фиксация нового файла с помощью git2go

В настоящее время я изо всех сил пытаюсь подготовить и зафиксировать файл в репозитории git в памяти (т.е. без записи файла на диск, его добавления и фиксации)

Вот сокращенная версия моего кода; это почти работает

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)
    }
}

Однако когда я запускаю его и смотрю ./repo, что-то не так. Как видно из git status, новый файл document_9.md помечен как удаляемый (т.е. git знает об этом, но его нет)

❯ 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

Посмотрев журнал, можно убедиться, что фиксация действительно сработала:

❯ 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

Я считаю, что пропускаю шаг. Каким-то образом мне нужно убедиться, что моя фиксация «синхронизирована» с файловой системой. Я подумал, что (на основании документации) это было достигнуто с помощью index.Write() и index.WriteTree(), но я не могу заставить его работать.

Мы будем очень благодарны за любой толчок в правильном направлении.


person Peter Yates    schedule 23.03.2017    source источник


Ответы (1)


Если вы хотите, чтобы рабочий каталог соответствовал состоянию нового коммита HEAD, вам необходимо проверить его (например, с помощью go-эквивалента git_checkout_head).

git_index_write_tree записывает объект дерева в базу данных объектов, а git_index_write записывает представление индекса в памяти на диск. Ни на рабочий каталог не влияет.

person Jason Haslam    schedule 23.03.2017
comment
Спасибо, это было правильное решение. Я неправильно понял документацию и подумал, что Write и WriteTree изменят оба. Для справки, я добавил следующее, чтобы выполнить проверку: repo.CheckoutHead(&git.CheckoutOpts{Strategy: git.CheckoutSafe | git.CheckoutRecreateMissing}) - person Peter Yates; 24.03.2017