2

Similar to this question, but instead of creating a new file, I'm trying to merge from origin. After creating a new index using Rugged::Repository's merge_commits, and a new merge commit, git reports the new file (coming from origin) as deleted.

Create a merge index,

> origin_target = repo.references['refs/remotes/origin/master'].target
> merge_index = repo.merge_commits(repo.head.target, origin_target)

and a new merge commit,

> options = {
     update_ref: 'refs/heads/master', 
     committer: {name: 'user', email: 'user@foo.com', time: Time.now},
     author: {name: 'user', email: 'user@foo.com', time: Time.now},
     parents: [repo.head.target, origin_target],
     message: "merge `origin/master` into `master`"}

and make sure to use the tree from the merge index.

> options[:tree] = merge_index.write_tree(repo)

Create the commit

> merge_commit = Rugged::Commit.create(repo, options)

Check that our HEAD has been updated:

> repo.head.target.tree
=> #<Rugged::Tree:16816500 {oid: 16c147f358a095bdca52a462376d7b5730e1978e}>                                             
 <"first_file.txt" 9d096847743f97ba44edf00a910f24bac13f36e2>                                                      
 <"second_file.txt" 8178c76d627cade75005b40711b92f4177bc6cfc>                                                             
 <"newfile.txt" e69de29bb2d1d6434b8b29ae775ad8c2e48c5391>

Looks good. I see the new file in the index. Write it to disk.

> repo.index.write
=> nil

...but git reports the new file as deleted:

$ git st
## master...origin/master [ahead 2]
 D newfile.txt

How can I properly update my index and working tree?

Community
  • 1
  • 1
  • Calling `repo.reset repo.head.target, :hard` unstages the "delete", and calling it again brings me back to a clean working directory. So I can confirm that `repo.index.write` is not writing the working directory, despite what is stated in [the docs](http://www.rubydoc.info/gems/rugged/0.21.3/Rugged/Index#write-instance_method). So how do I update the working directory? – occamsquattro Jan 15 '15 at 22:15

1 Answers1

1

There is an important distinction between the Git repository and the working directory. While most common command-line git commands operate on the working directory as well as the repository, the lower-level commands of libgit2 / librugged mostly operate on only the repository. This includes writing the index as in your example.

To update the working directory to match the index, the following command should work (after writing the index):

options = { strategy: force }
repo.checkout_head(options)

Docs for checkout_head: http://www.rubydoc.info/github/libgit2/rugged/Rugged/Repository#checkout_head-instance_method

Note: I tested with update_ref: 'HEAD' for the commit. I'm not sure if update_ref: 'refs/heads/master' will have the same effect.

Ralf
  • 14,655
  • 9
  • 48
  • 58