git-subir-cambios-con-push

Pushing Your Changes to the Server with git push

  • 7 min

The git push command (to push) is the operation responsible for sending your local commits to the remote repository and updating the server to reflect your new history.

In the previous article, we learned how to bring the team’s work to our computer using fetch and pull. Now it’s time to do exactly the opposite path: publish your code so the rest of the team can download and use it.

Unlike systems like Dropbox or Google Drive, which continuously sync files in the background, in Git synchronization is manual and intentional.

You decide the exact moment when your work is ready to be uploaded to the cloud (usually to origin).

Let’s see how to use git push, and how to solve the problems you might encounter when using this command (and how to fix them).

Normal Push

If you are working on a branch that already exists both on your computer and on the server (for example, the main branch), the operation is straightforward.

Simply open the terminal and execute:

git push
Copied!

What does Git do under the hood?

  1. Compares your local branch with the server’s.
  2. Identifies which commits you have that the server doesn’t.
  3. Packages those commits, sends them over the network, and tells the server: “Move your main tag forward to point to this new commit”.

<lll-ui-git-timeline config=’{ “scenarios”: [ { “title”: “Before the Push”, “commits”: [ {“id”:“A”, “col”:0}, {“id”:“B”, “parent”:“A”, “col”:1}, {“id”:“C”, “parent”:“B”, “col”:2} ], “branches”: { “origin/main”: { “target”: “B”, “offset”: 50 }, “main”: { “target”: “C”, “offset”: -50 } }, “head”: { “target”: “main”, “type”: “branch” }, “terminal”: { “cmd”: ”You can't use 'macro parameter character #' in math modegit push", "comment": "# main has C, which origin/main doesn't know yet." } }, { "title": "After the Push", "commits": [ {"id":"A", "col":0}, {"id":"B", "parent":"A", "col":1}, {"id":"C", "parent":"B", "col":2} ], "branches": { "origin/main": { "target": "C", "offset": 50 }, "main": { "target": "C", "offset": -50 } }, "head": { "target": "main", "type": "branch" }, "terminal": { "cmd": "git push”, “comment”: ”# origin/main advances to C. Synchronized.” } } ] }’>

When Git Rejects Your Push

Now things get a bit more complicated, Git has rejected your Push. You tried to push, but your console fills with red letters:

! [rejected]        main -> main (fetch first)
error: failed to push some refs to 'github.com:...'
hint: Updates were rejected because the remote contains work that you do not have locally.
Copied!

Blah blah blah, Push rejected

Don’t worry, nothing is broken. This is simply Git’s defense mechanism kicking in. Git is protecting the server’s code.

What happened? The server detected that its history has new commits that you don’t have on your local machine. Someone (a teammate) did a push before you.

If Git accepted your upload right now, your history would overwrite your teammate’s and their commits would be deleted. That’s why it rejects the operation.

The Solution: Download and Integrate

The error message itself gives you the clue: (fetch first).

As we saw in the previous article, you have to bring the server’s code to your machine, integrate it with yours, and then upload the final result.

Download and integrate: Run git pull. Git will merge your teammate’s commit with yours.

Push again: Now that your local history is up-to-date and contains all the changes, run git push again. This time it will go through without issues.

<lll-ui-git-timeline config=’{ “scenarios”: [ { “title”: “Initial Situation”, “commits”: [ {“id”:“A”, “col”:0}, {“id”:“B”, “parent”:“A”, “col”:1}, {“id”:“C”, “parent”:“B”, “msg”:“Teammate”, “col”:2, “row”:-1}, {“id”:“D”, “parent”:“B”, “msg”:“You”, “col”:2, “row”:1} ], “branches”: { “origin/main”: “C”, “main”: “D” }, “head”: { “target”: “main”, “type”: “branch” }, “terminal”: { “cmd”: ”You can't use 'macro parameter character #' in math modegit pull", "comment": "# We download and integrate the teammate's work." } }, { "title": "After the Pull", "commits": [ {"id":"A", "col":0}, {"id":"B", "parent":"A", "col":1}, {"id":"C", "parent":"B", "msg":"Teammate", "col":2, "row":-1}, {"id":"D", "parent":"B", "msg":"You", "col":2, "row":1}, {"id":"M", "parent":"C", "parent2":"D", "msg":"Merge", "col":3, "row":0} ], "branches": { "origin/main": { "target": "C", "offset": -50 }, "main": { "target": "M", "offset": 50 } }, "head": { "target": "main", "type": "branch" }, "terminal": { "cmd": "git push”, “comment”: ”# Now main contains everything. The push goes through without issues.” } }, { “title”: “After the Push”, “commits”: [ {“id”:“A”, “col”:0}, {“id”:“B”, “parent”:“A”, “col”:1}, {“id”:“C”, “parent”:“B”, “msg”:“Teammate”, “col”:2, “row”:-1}, {“id”:“D”, “parent”:“B”, “msg”:“You”, “col”:2, “row”:1}, {“id”:“M”, “parent”:“C”, “parent2”:“D”, “msg”:“Merge”, “col”:3, “row”:0} ], “branches”: { “origin/main”: { “target”: “M”, “offset”: 50 }, “main”: { “target”: “M”, “offset”: -50 } }, “head”: { “target”: “main”, “type”: “branch” }, “terminal”: { “cmd”: ”$ git push”, “comment”: ”# origin/main catches up to main at M. Everything synchronized.” } } ] }’>