Enviar um novo arquivo para git usando o Rugged

Esta dica demonstra como usar o Rugged para enviar um novo arquivo ao git e deixar um diretório de trabalho limpo.

Rugged é uma biblioteca que fornece ligações de API Ruby para libgit2 , uma implementação C das operações git. O Rugged está substituindo rapidamente o grão e bibliotecas Ruby semelhantes porque executa operações no repositório git usando chamadas de API diretas em vez de chamar git como um comando do sistema.

Uma das primeiras coisas que você deseja fazer ao usar o Rugged é confirmar um arquivo programaticamente. Ao contrário das bibliotecas git que você pode ter usado no passado, Rugged (e libgit2) requer um entendimento mais profundo de como um commit é estruturado e a interação entre o repositório git (ou seja, o banco de dados) e o diretório de trabalho.

Começaremos criando um repositório sem usar o Rugged para estabelecer um ponto de partida.

git_email = 'octocat@github.com'
git_name
= 'The Octocat'
repo_name
= 'sample-repo'

Dir.mkdir repo_name
Dir.chdir repo_name do
File.open 'README.md', 'w' do |f|
f
.write %(# READMEnnYou will read me and be informed.)
end
`git init .`
`git add README.md`
`git commit -m "add README" --author "#{git_name} <#{git_email}>" README.md`
end

Você pode inspecionar o repositório para ver se ele tem um arquivo e um commit.

Agora usaremos o Rugged para remover o arquivo README.md e substituí-lo por um arquivo README.adoc.

require 'rugged'

# (1)
repo
= Rugged::Repository.new repo_name

# (2)
repo
.checkout 'refs/heads/master'

# (3)
index
= repo.index

# (4)
File.unlink File.join(repo.workdir, 'README.md')
index
.remove 'README.md'

# (5)
File.open File.join(repo.workdir, 'README.adoc'), 'w' do |f|
f
.write %(= READMEnnYou will read me and be informed.)
end
index
.add path: 'README.adoc',
oid
: (Rugged::Blob.from_workdir repo, 'README.adoc'),
mode
: 0100644

# (6)
commit_tree
= index.write_tree repo

# (7)
index
.write

# (8)
commit_author
= { email: git_email, name: git_name, time: Time.now }
Rugged::Commit.create repo,
author
: commit_author,
committer
: commit_author,
message
: 'Adding README from which all shall learn',
parents
: [repo.head.target],
tree
: commit_tree,
update_ref
: 'HEAD'

Aqui está o que este código está fazendo:

  • (1) Carregue o repositório no Rugged
  • (2) Certifique-se de que estamos no ramo certo (por exemplo, refs / heads / master)
  • (3) Recupere uma referência ao índice do repositório para este ramo
  • (4) Remova o README.md do disco e do índice do repositório
  • (5) Grave o arquivo README.adoc no disco e adicione-o ao índice do repositório
  • (6) Grave as alterações feitas no índice no repositório git (ou seja, o banco de dados git)
  • (7) Sincronizar o índice e o diretório de trabalho (não modifica o diretório de trabalho)
  • (8) Crie um novo commit e atualize o HEAD para apontar para ele

Se você tiver uma configuração remota chamada ‘origin’, poderá seguir o commit com uma operação push:

repo.push 'origin', ['refs/heads/master']

Embora isso pareça ser uma série de etapas, uma vez que você entenda a distinção entre o índice, a árvore e o diretório de trabalho, você apreciará a profundidade de controle que esta API oferece para interagir com um repositório git.

NOTA: Se você não estiver tentando manter o diretório de trabalho em sincronia, poderá pular as etapas que adicionam e removem explicitamente os arquivos, bem como a chamada para index.write.