tags:

views:

59

answers:

2

Please help me understand how git works.

I clone my remote repository on two different machines.

I edit the same file on both machines.

I successfully commit and push the update from the first machine to the remote repository. I then try to push the update on the second machine, but get an error:

! [rejected]        master -> master (non-fast-forward)

I understand why I received the error. How can I merge my changes into the remote repo? Do I need to pull the remote repo first?

+2  A: 

Yes.

Merging only happens on a pull; a push will only perform a fast-forward (unless you force it, but that loses work). Once you've pulled and successfully merged, the push will be a fast-forward.

git-push has some nice illustrations.

jleedev
+4  A: 

Yes, after remote repository rejected push as non fast-forward, you need to pull from remote repository (this would do a merge, which means that you might need to resolve merge conflict -- don't forget to commit merge conflict resolution in that case), and then push again.


  1. After comitting changes on machines A and B you have the following situation:

    • ''remote repository''

      *---*---*---C
      

    • ''machine A''

      *---*---*---C---A
      

    • ''machine B''

      *---*---*---C---B
      

  2. After pushing from machine A to remote repository you have:

    • ''remote repository''

      *---*---*---C---A
      

    • ''machine A''

      *---*---*---C---A
      

    • ''machine B''

      *---*---*---C---B
      
      Push from machine B would correctly refuse to "overwrite" commit A with commit B.

  3. After pulling from remote repository on machine B you have:

    • ''remote repository''

      *---*---*---C
      

    • ''machine A''

      *---*---*---C---A
      

    • ''machine B''

      *---*---*---C---B----M
                  \       /
                   \--A--/
      
      Just in case this ASCII-art gets mangled: there is form from commit C, and two branches are merged as commit M.

    Now the push would be fast-forward

  4. After pushing from machine B to remote repository

    • ''remote repository''

      *---*---*---C---B----M
                  \       /
                   \--A--/
      

    • ''machine A''

      *---*---*---C---A
      

    • ''machine B''

      *---*---*---C---B----M
                  \       /
                   \--A--/
      

  5. Now on machine A you need to pull from repository before starting any new work, to be up to date. Pull would fast-forward, which means that there wouldn't be created any new merge commit. Now all three machines have the same state of repository

    • ''remote repository''
      ''machine A''
      ''machine B''
      *---*---*---C---B----M
                  \       /
                   \--A--/
      

HTH

Jakub Narębski
The illustration really helped me get a clear idea of what's going on. Thanks!
Marco