1

Using Rugged, I create a new branch from master (let's call it new_branch), modify a file and create a commit for that. Now I want to merge this branch into master, push master to remote and delete new_branch.

At the point of running the code below there are no modified files and no staged files on either branch as the modified is committed into new_branch.

This is the code I use:

        from_branch = @repo.head.name
        their_commit = @repo.branches[into_branch].target_id
        our_commit = @repo.branches[from_branch].target_id

        index = @repo.merge_commits(our_commit, their_commit)

        if index.conflicts?
            # conflicts. deal with them
        else
            # no conflicts
            commit_tree = index.write_tree(@repo)
            @repo.checkout(into_branch)

            commit_author = { email: GIT_EMAIL, name: GIT_NAME, time: Time.now }
            Rugged::Commit.create(@repo,
                committer: commit_author,
                message: "Merge #{from_branch} into #{into_branch}",
                parents: [@repo.head.target, our_commit], 
                tree: commit_tree,
                update_ref: @repo.branches[into_branch].canonical_name)

            @repo.push('origin', [@repo.head.name], { credentials: @cred })
            @repo.branches.delete(from_branch)
        end

This works as expected (modified file is merged into master, it is pushed to remote and the new branch is delete), however once it's done, I am left with the modified file showing under master as modified and staged, ready to be committed while there shouldn't be any modified files in the working directory and nothing staged. Everything should be up-to-date.

Khash
  • 2,500
  • 4
  • 30
  • 56

1 Answers1

2

In your code you are updating an arbitrary branch, so the index and worktree should not be of concern in the general case.

If you are merging into the current branch, then (and only then) you are missing the steps to update both the index and the worktree with the results of the merge. You can use

@repo.checkout_tree(commit_tree)

to checkout the files as they are on the resulting commit. This will also update the repository's index file to have the contents of that tree. You can then update the current branch to point to the merge commit.

You have a call to @repo.checkout(into_branch) but since you already seem to be in into_branch in your case, that will at best do nothing. You need to checkout the result of the merge, the branch, index or workdir are not touched by the @repo.merge_commits() call.

Carlos Martín Nieto
  • 5,207
  • 1
  • 15
  • 16