Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Repository.mergeBranches creates dirty index after a non-conflicting merge #1217

Open
rcjsuen opened this issue Feb 8, 2017 · 6 comments · May be fixed by #1271
Open

Repository.mergeBranches creates dirty index after a non-conflicting merge #1217

rcjsuen opened this issue Feb 8, 2017 · 6 comments · May be fixed by #1271

Comments

@rcjsuen
Copy link
Member

rcjsuen commented Feb 8, 2017

  1. Run the code below.
  2. You will see that stuff gets printed indicating a dirty index.
  3. cd merge-commit-bug
  4. git status
> git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   test.txt

All the tests in merge.js merges two random branches so the bug doesn't appear. The bug will only surfaces if you merge HEAD with another branch.

var path = require("path");
var fs = require("fs");
var git = require('.');
var repoDir = path.resolve(__dirname, "merge-commit-bug");
var name = "test.txt";
var name2 = "test2.txt";
var fileName = path.resolve(repoDir, name);
var fileName2 = path.resolve(repoDir, name2);
var repository;
var index;
var head;
var leftBranch;

return git.Repository.init(repoDir, 0)
.then(function(repo) {
	repository = repo;
	fs.writeFileSync(fileName, "A", null);
	return repository.refreshIndex();
})
.then(function(idx) {
	index = idx;
	return index.addByPath(name);
})
.then(function() {
	return index.writeTree();
})
.then(function(oid) {
	return repository.createCommit("HEAD",
		git.Signature.default(repository),
		git.Signature.default(repository),
		"message", oid, []);
})
.then(function(oid) {
	head = oid;
	fs.writeFileSync(fileName, "B", null);
	return repository.refreshIndex();
})
.then(function(idx) {
	index = idx;
	return index.addByPath(name);
})
.then(function() {
	return index.write();
})
.then(function() {
	return index.writeTree();
})
.then(function(oid) {
	return repository.createCommit("HEAD",
		git.Signature.default(repository),
		git.Signature.default(repository),
		"left", oid, [ head ]);
})
.then(function(left) {
	return repository.getCommit(left);
})
.then(function(commit) {
	return git.Branch.create(repository, "leftBranch", commit, false);
})
.then(function(branch) {
	leftBranch = branch;
	return repository.getCommit(head);
})
.then(function(commit) {
	return git.Reset.reset(repository, commit, git.Reset.TYPE.HARD, {});
})
.then(function() {
	fs.writeFileSync(fileName2, "C", null);
	return repository.refreshIndex();
})
.then(function(idx) {
	index = idx;
	return index.addByPath(name2);
})
.then(function() {
	return index.write();
})
.then(function() {
	return index.writeTree();
})
.then(function(oid) {
	return repository.createCommit("HEAD",
		git.Signature.default(repository),
		git.Signature.default(repository),
		"right", oid, [ head ]);
})
.then(function(commit) {
	return repository.mergeBranches("master", leftBranch, git.Signature.default(repository), null, null);
})
.then(function() {
	return repository.getStatus();
})
.then(function(statuses) {
	console.log(statuses);
	console.log(statuses[0].path());
})
.catch(function(err) {
	console.log(err);
});
@raqqun
Copy link

raqqun commented Feb 18, 2017

Unfortunately i'm having the exact same problem.

The code below produces a merge and a commit with message "Merged master into dev".
But then when i'm doing a git status i'm getting :

On branch dev
Your branch is ahead of 'origin/dev' by 156 commits.
  (use "git push" to publish your local commits)
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   .gitignore
	modified:   license.txt
	modified:   readme.html
	modified:   wp-activate.php
	modified:   wp-admin/about.php
	modified:   wp-admin/admin-ajax.php
        .....

which is odd since the merge produced earlier has the files committed.

I'm using the code below to fetch origin and merge the two branches.

    NodeGit.Repository.open(path).then(function(repoResult) {
        repo = repoResult;
    })
    .then(function() {
        repo.fetch('origin', {
            callbacks: {
                credentials: function(url, userName) {
                    return NodeGit.Cred.sshKeyMemoryNew(userName, publickey, privatekey, '');
                }
            }
        })
    })
    .then(function() {
        return repo.mergeBranches('dev', 'master');
    })
    .catch(function(err) {
        console.log(err);
    });

@rcjsuen
Copy link
Member Author

rcjsuen commented Feb 19, 2017

@raqqun I suppose you could try working around the problem by switching your HEAD to point elsewhere and/or by performing a hard reset after the merge.

@neloe
Copy link

neloe commented May 17, 2017

I am having this same problem; if I merge a branch into master, the merge works (the commit is there, and it is appropriate). After the merge, git status shows that I have uncommitted (but staged) changes; these changes would undo the previous commit. The problem with a hard reset after the merge is that it might clobber other staged (but uncommitted) changes. I need to play around with git itself to see what it does in this situation.

I'll try moving HEAD around and see what that does.

This is snippets of the code that's exhibiting this behavior (with the reset in there). Unfortunately, this clobbers my staged and/or unstaged changes from already tracked files.
https://gist.github.com/neloe/cb486f73d73a34f7e890d7c827483c54

@Nard-Dog
Copy link

Nard-Dog commented Jun 1, 2017

Seeing the same issue with nodegit v0.19.0 and git v2.6.2

Steps to reproduce:

  1. Checkout a branch
  2. Edit a file
  3. Refresh Index
  4. Add all to the index
  5. Create a commit
  6. Push commit to remote
  7. Checkout other branch
  8. Merge first branch into other branch
  9. Push to remote.

Expected:
git status should show that I have a clean index and no staged changes.

Actual:
git status reads that I have staged changes which would negate the ones I just committed.

@kryp71c
Copy link

kryp71c commented Sep 21, 2017

I had a similar issue. What worked for me was using the example from https://github.com/nodegit/nodegit/blob/master/examples/add-and-commit.js
which adds a couple of steps between writeTree and createCommit:

.then(function() {
  return index.writeTree();
})
.then(function(oidResult) {
   oid = oidResult;
   return nodegit.Reference.nameToId(repo, "HEAD");
})
.then(function(head) {
   return repo.getCommit(head);
})
.then(function(parent) {
  return repository.createCommit("HEAD",
    git.Signature.default(repository),
    git.Signature.default(repository),
    "right", oid, [ parent ]);
})

@lal12
Copy link

lal12 commented Nov 22, 2021

I had a similar issue. In my case the issue was that I fetched refs/heads/master:refs/heads/master instead of refs/heads/master:refs/remotes/origin/master.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants