Skip to content

Can git commit signing implementation be updated to be easier to use? #992

@Sparc0

Description

@Sparc0

Been trying to implement signing of commits in a project we use.
I have sort of gotten it to work but the implementation between a none signed commit and signed commit differs a lot and i would like it to become much easier so the code in the project i use gets cleaner.

Basically this is how we implemented none signed today, it works for a newly created bare repo also.

oid = repo.write("This is a blob.", :blob)
index = repo.index
index.read_tree(repo.head.target.tree)
index.add(:path => "README.md", :oid => oid, :mode => 0100644)

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

options[:author] = { :email => "testuser@github.com", :name => 'Test Author', :time => Time.now }
options[:committer] = { :email => "testuser@github.com", :name => 'Test Author', :time => Time.now }
options[:message] ||= "Making a commit via Rugged!"
options[:parents] = repo.empty? ? [] : [ repo.head.target ].compact
options[:update_ref] = 'HEAD'

@commitref = Rugged::Commit.create(repo, options)

index.write

But to make signed commits in a new bare repo the first part is the same with options but alot after differs.

oid = repo.write("This is a blob.", :blob)
index = repo.index
index.read_tree(repo.head.target.tree)
index.add(:path => "README.md", :oid => oid, :mode => 0100644)

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

options[:author] = { :email => "testuser@github.com", :name => 'Test Author', :time => Time.now }
options[:committer] = { :email => "testuser@github.com", :name => 'Test Author', :time => Time.now }
options[:message] ||= "Making a commit via Rugged!"
options[:parents] = repo.empty? ? [] : [ repo.head.target ].compact
options[:update_ref] = 'HEAD'

# Create a string of the contents to be commited.
content = Rugged::Commit.create_to_s(repo, options)

# Sign the string.
crypto = GPGME::Crypto.new(armor: true)
signature = crypto.detach_sign(content, signers: @cfg.sign_key).to_s.strip

# Create a commit using the string and signature. 
@commitref = Rugged::Commit.create_with_signature(repo, content, signature, 'gpgsig')

# After doing this create_with_signature calling for index.write does not work.
# and i have to do this repo references else i cant see any commits when i do git log --show-signature

# Check if HEAD exists and handle accordingly
if repo.references.exist?("HEAD") && !repo.head_unborn?
  # HEAD exists and points to a real branch
  repo.references.update(repo.head.name, @commitref)
else
  # HEAD doesn't exist or is unborn - create default branch
  repo.references.create("refs/heads/master", @commitref)
end

I would like the implementation of signed commits to be as easy as doing a normal commit just that i have to specify the key i want to sign with.
e.g

# Just want a function i can call for as easy as Commit.create that signs my commits and update the reference on disk. 
Rugged::Commit.commit_with_signature(repo, options, signature)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions