Bug 379681 - Pull with rebase removes local empty commit
Summary: Pull with rebase removes local empty commit
Status: NEW
Alias: None
Product: JGit
Classification: Technology
Component: JGit (show other bugs)
Version: unspecified   Edit
Hardware: All All
: P3 minor (vote)
Target Milestone: ---   Edit
Assignee: Project Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-05-16 08:51 EDT by Mikael Karlsson CLA
Modified: 2012-05-16 12:52 EDT (History)
1 user (show)

See Also:


Attachments
JUnit test to reproduce the bug (8.58 KB, application/octet-stream)
2012-05-16 08:52 EDT, Mikael Karlsson CLA
no flags Details
JUnit test to reproduce the bug. (8.02 KB, application/octet-stream)
2012-05-16 09:03 EDT, Mikael Karlsson CLA
no flags Details
JUnit test to reproduce the bug (8.01 KB, application/octet-stream)
2012-05-16 09:04 EDT, Mikael Karlsson CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Mikael Karlsson CLA 2012-05-16 08:51:35 EDT
Build Identifier: JGit commit 37307af from https://github.com/eclipse/jgit/

When doing a pull using rebase when having a local commit (not pushed upstream), the local commit disappears.

Consider the attached JUnit test case. It should be run inside the JGit project to make sure the RepositoryTestCase class is available.

The test fails because the latest commit ("HEAD") is not the commit that was created locally before the pull. Instead, the locally created commit disappears completely from the log.

Running "git log" (using native git) inside the repos that the test creates confirms that the commit is actually gone.

Note: Pulling with rebase requires "rebase = true" for your branch in the config file, e.g. "git config branch.master.rebase true". The 

This is how you do this manually with native git:
    cd /tmp
    mkdir jgit
    cd jgit
    git init source
    git init target
    cd source
    echo "Hello world" > SomeFile.txt
    git add SomeFile.txt
    git commit -m "Initial commit for source"

    cd ../target
    git config branch.master.remote origin
    git config branch.master.merge "refs/heads/master"
    git remote add origin /tmp/jgit/source
    git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
    git pull origin master
    git config branch.master.rebase true

    cd ../source
    echo "Source change" > SomeFile.txt
    git add SomeFile.txt
    git commit -m "Source commit message for rebase flag test"

    cd ../target
    echo "New file from target" > newFile.txt
    git add newFile.txt
    git commit -m "Target commit message for rebase flag test"
    git log
    git pull origin master (should do rebase by default)
    git log
    
Now compare output to log before pull.

The first git log command will give us:
Target commit message for rebase flag test
Initial commit for source

After the pull (with rebase), git log gives us:
Target commit message for rebase flag test
Source commit message for rebase flag test
Initial commit for source

In the JGit test, the log looks like this:
Source commit message for rebase flag test
Initial commit for source

As you can see, the "Target commit message for rebase flag test" commit mysteriously disappeared.

I'll be happy to assist you with more information. Just let me know.

Reproducible: Always

Steps to Reproduce:
1. Run the attached test
2. Check the output
3. Compare output with doing the same thing manually with git (instructions included)
Comment 1 Mikael Karlsson CLA 2012-05-16 08:52:45 EDT
Created attachment 215706 [details]
JUnit test to reproduce the bug
Comment 2 Mikael Karlsson CLA 2012-05-16 09:03:03 EDT
Created attachment 215707 [details]
JUnit test to reproduce the bug.
Comment 3 Mikael Karlsson CLA 2012-05-16 09:04:31 EDT
Created attachment 215708 [details]
JUnit test to reproduce the bug
Comment 4 Mikael Karlsson CLA 2012-05-16 09:09:26 EDT
Pulling without rebase keeps the local commit.

This is the resulting log in the JUnit test case if not using rebase (commenting out "targetConfig.setBoolean("branch", "master", "rebase", true);"):

Merge branch 'master' of /tmp/jgit/target/trash/test1337173643647_0
Target commit message for rebase flag test
Source commit message for rebase flag test
Initial commit for source
Comment 5 Mikael Karlsson CLA 2012-05-16 09:55:17 EDT
It turns out I have an error in my test case. The file (newFile.txt) for the commit called "Target commit message for rebase flag test" is never created, but the commit is still created.

When I change the JUnit test case so that the file is actually created, I get the expected result with all 3 commits in the target repo, and the test passes.

However, it is possible to create an empty commit in JGit, but not in standard git. I would say this is a bug, right?

Also, if running the JUnit test up until just before the pull is made, and then doing the pull from the command line with standard git, the rebase is made correctly, when JGit would delete one of the commits. This should also be a bug, but a minor one.

I suggest that this bug report handles the "missing commit after doing pull rebase having a local commit without any files" issue, and I will experiment some more and probably create a new bug report for the "possible to create commit without any files" issue.
Comment 6 Robin Stocker CLA 2012-05-16 10:23:44 EDT
Creating an empty commit in Git is possible:

  git commit --allow-empty

But maybe CommitCommand should throw an exception when there are no changes and a new setAllowEmpty flag was not set.

The other issue, as you mention, is that rebase drops the empty commit, which is not nice..