Search code examples
gitgithubgit-mergegit-pushgit-pull

Branch is merging into self on git push


I have a repo set up on GitHub, with a Dev branch, which I clone to my local machine using:

git clone https://github....

I then switch to my Dev branch using:

git checkout -b Dev

I then pull just to make sure all is up to date

git pull origin Dev

I am now in my Dev branch, write some code and add the files using:

git add filename

I then commit using:

git commit -m "message"

I then push using:

git push origin Dev

This works all good. A second user then comes along and enters some code. At the same time I am working on a separate file but we are working on the same branch. I add and commit as before. However, when I try to push, I receive the following:

To https://github.com/ex/ex.git ! [rejected]
Dev -> Dev (fetch first) error: failed to push some refs to 'https://github.com/ex/ex.git' hint: Updates were rejected because the remote contains work that you do hint: not have locally. This is usually caused by another repository pushing hint: to the same ref. You may want to first merge the remote changes (e.g., hint: 'git pull') before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details.

I do as it says and perform:

git pull origin Dev

I can then push as before and all seems well. However, back on GitHub when I check the commit history I see this:

 Merge branch 'Dev' of https://github.com/ex/ex into Dev

amongst the commits I just added. Why is this merge happening? How can I stop this from happening?


Solution

  • The merge was needed because you and your second user diverged; each of you committed something off of a common base. Getting back in sync requires combining the two development paths.

    A 'merge commit' does no harm whatsoever; it really isn't worth worrying about it. However, if you want to avoid it, often to keep a cleaner history, you perform:

    git pull --rebase ...
    

    which will rebase your new commits onto whatever is pulled from the repository. The history will then appear linear.

    Here is an example. A repository with two branches:

    $ git log --oneline --graph --all    
    * 678ea83 c
    | * 2c1e48f b
    |/  
    * 5836f6f a
    

    The result of merge:

    $ git merge dev
    Merge made by the 'recursive' strategy.
     0 files changed
     create mode 100644 b
    $ git log --oneline --graph --all
    *   6d50134 Merge branch 'dev'
    |\  
    | * 2c1e48f b
    * | 678ea83 c
    |/  
    * 5836f6f a
    

    Alternately, the result of rebase:

    $ git rebase dev
    First, rewinding head to replay your work on top of it...
    Applying: c
    $ git log --oneline --graph --all
    * 89a3771 c
    * 2c1e48f b
    * 5836f6f a