как я могу использовать Rugged для создания и фиксации файла, например, из командной строки?

я пытаюсь использовать Rugged, чтобы сделать что-то довольно простое: создать и зафиксировать файл, оставив репозиторий в том же состоянии, что и при выполнении:

git init
echo "blah blah blah" > blah.txt
git add blah.txt
git commit -m "write blah.txt"

что оставляет git status печать

On branch master
nothing to commit, working directory clean

я использую код, адаптированный из readme защищенного репозитория, который сводится к к:

name = "blah.txt"
repo = Rugged::Repository.init_at dir

File.open File.join(dir, name), 'w' do |f|
  f.write content
end

oid = Rugged::Blob.from_workdir repo, name
index = repo.index

index.add(:path => name, :oid => oid, :mode => 0100644)

options = {}
options[:tree] = index.write_tree(repo)

options[:author] = {  :email => "[email protected]",
                      :name => 'Test Author',
                      :time => Time.now }
options[:committer] = { :email => "[email protected]",
                        :name => 'Test Author',
                        :time => Time.now }
options[:message] =  "write #{ name }"
options[:parents] = repo.empty? ? [] : [ repo.head.target ].compact
options[:update_ref] = 'HEAD'

commit = Rugged::Commit.create(repo, options)

это, кажется, оставляет репозиторий в правильном состоянии, но рабочий каталог в странном месте с git status печатью

On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    deleted:    blah.txt

Untracked files:
  (use "git add <file>..." to include in what will be committed)

    blah.txt

я не понимаю, что, по мнению git, происходит в этот момент (blah.txt подготовлено для удаления?). выполнение git reset --hard возвращает рабочий каталог в желаемое состояние, насколько я могу судить.

Заранее спасибо за помощь.


person nrser    schedule 03.07.2014    source источник
comment
Что вы получаете с repo.head?   -  person BroiSatse    schedule 03.07.2014
comment
@BroiSatse после того, как скрипт repo.head возвращает #<Rugged::Reference:70351778973300 {name: "refs/heads/master", target: #<Rugged::Commit:70351778972640 {message: "write blah.txt", tree: #<Rugged::Tree:70351778972520 {oid: 0066195e7906b164d170885e8c341fd1f1027e3d}> <"blah.txt" f0c1bd0931281f8df0574ff2a1e106547b4366cb> , parents: []}>}>   -  person nrser    schedule 04.07.2014


Ответы (1)


Вы забыли сохранить изменения в файле index. Вы обновили ссылку, чтобы указать на новую фиксацию, но индекс не изменился (поскольку вы никогда не вызываете Index#write), так что с точки зрения git удаление выполняется поэтапно, потому что файл не находится в индексе, как если бы вы пробежал git rm blah.txt.

person Carlos Martín Nieto    schedule 03.07.2014
comment
как бы я изменил приведенный выше код, чтобы исправить это? или какой код выполнит это? простите меня, но я мало знаю о внутренностях git и не нахожу документации по защищенным. приведенный выше пример адаптирован из примера записи в файле readme проекта: github. com/libgit2/rugged#write-to-a-repository - person nrser; 04.07.2014
comment
Я бы добавил то, что я сказал, добавил вызов Index#write, чтобы сохранить ваши изменения в индексе на диске, в вашем коде это будет index.write(). - person Carlos Martín Nieto; 04.07.2014
comment
да, это, кажется, исправить это. любая идея, почему это отсутствует в rugged документах на github.com/libgit2/rugged #запись-в-репозиторий? есть ли какая-то причина, по которой вы не хотели бы писать индекс перед фиксацией? - person nrser; 07.07.2014
comment
Этот пример не эмулирует команду git-commit, он просто создает новую фиксацию. Индекс — это не просто файл .git/index, а структура данных, часто хочется использовать ее, не затрагивая файл индекса. - person Carlos Martín Nieto; 07.07.2014
comment
хорошо, итак, в соответствии с первоначальным вопросом, как можно эмулировать команды git add ...; git commit? это то, что я пытаюсь сделать. я заметил, что после добавления вызова index.write изменения в blah.txt не отображаются, например, как изменения в git status, и я предполагаю, что из вашего ответа могут быть и другие проблемы. - person nrser; 07.07.2014
comment
git add будет чем-то вроде idx = repo.index; idx.add(String); idx.write, для фиксации это зависит от того, какие параметры вы хотите эмулировать. Простейшая форма - это то, что показано в README, передайте ветку, которую вы хотите обновить. - person Carlos Martín Nieto; 07.07.2014