Is Git Smart Enough to Merge After Refactoring

Assume I have a class.

package org.my.domain;

public class BestClassEver{}

My Workflow

Through some refactoring, I change this class’s package.

package org.another.domain;

public class BestClassEver{}

I commit this to my local repository using git and push it to a remote repository.

git add .
git commit -m "Refactoring"
git push origin master

Another Developer’s Workflow

Another developer modifies the class, without pulling my changes.

package org.my.domain;

public class BestClassEver{
    private String something;
}

Then commits and pushes to the remote repository

git add .
git commit -m "Some Changes"
git push origin master

Questions

  1. Will Git merge the other developer’s changes into the class?
  2. If not, what happens?
  3. Is this workflow something that needs to be coordinated amongst the team?

  • including files in eclipse after git checkout
  • IllegalStateException with naming parameters in tomcat
  • Maven build igonres code changes
  • Include GIT installation in a Java app
  • Heroku Integration with Intelij
  • Eclipse can not commit all files to Git
  • Importing bitbucket project via GIT to Eclipse failed with errors
  • This compilation unit is not on the build path of a Java project
  • 4 Solutions collect form web for “Is Git Smart Enough to Merge After Refactoring”

    1. Git won’t allow the other developer to push his changes without pulling.

    It will throw an error that both refs don’t match and therefore his local branch needs to be updated with the remote refs.

    That’s pretty much all there is to know about that. If there are changes in the remote repository, unless you do a forced push, git won’t allow you to push changes if there are changes in the remote.

    EDIT

    Once he pulls, if there are any conflicts in the file, the developer will have to correct any conflicts, commit them and only then he will be able to push.

    If there are no conflicts, git will automatically merge those changes and the developer will be able to push after the pull.

    EDIT AGAIN

    I didn’t realize that you were moving the file. In any case, running git status would give you an idea as to the state of your local repository after a pull. If there was any conflicts, you’d be able to correct them.

    NOTE

    On git rebase or git pull --rebase are usually used to give you a much cleaner commit history as they will pretty much will apply any local changes on top of any other changes that were pulled.

    On the other hand, git pull and git merge will usually make an extra commit to link the changes on the branches.

    For more information take a look at this guide Git Rebasing

    It is always good idea to let people work on different parts of program.

    Merge or rebase in this case should be fully automatic, but in real world it is always a bit dramatic and sometimes there are some conflicts. Of course, this merge/rebase will be done after server rejects push for beeing non-fast-forward.

    When such thing fails, some workarounds include:

    1. Just repeating “refactoring” in the other branch prior to merging;
    2. Converting the work to patch (git format-patch), editing the patch (applying that “refactor” to it) and applying the edited patch (git am). It is like manual rebasing.

    I think it’s better to separate merge-complicating refactoring (one that involves renaming, for example) and usual minor refactoing.

    Sometimes for a merge-complicating refactoing a script can be written (such as find -name '*.c' -exec sed 's/something/anything/g' -i '{}' ';'). The script be used to repeat the refactoring multiple times in various places when we need it, so avoiding to merge refactored code with non-refactored one.

    YES. Git is able to identify those changes. I am working on a project using git on my own fork (forked from origin). In the meantime another developer refactored the codebase on the original fork, which includes changing package structure.

    I used the following commands:

    • git stash save // this saves all your work onto a personal stash
    • git pull // fetches all the latest changes on the primary fork and merges
    • git stash apply stash@{0} // or whatever the stash is where you saved your personal work

    Now you will have the refactored codebase+your changes. You can now commit without any conflict and the packaging will not be changed.

    Just note that in my case I waited for the original fork to be refactored and then I committed my changes, which are only changes to few files and not repackaging.

    Also note that if you have added new files, then you might have to edit a few imports to make sure the imports are correct.
    eg. import org.my.domain;
    should now be edited to: import org.another.domain;

    Git Baby is a git and github fan, let's start git clone.