Chapters

Hide chapters

Git Apprentice

Second Edition · Git 2.32 · Console

Section I: Beginning Git

Section 1: 11 chapters
Show chapters Hide chapters

9. Syncing With a Remote
Written by Bhagat Singh & Chris Belanger

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

Up to this point in the book, you’ve worked pretty much exclusively on your local system, which isn’t to say that’s a bad thing — having a Git repository on your local machine can support a healthy development workflow, even when you are working by yourself.

But where Git really shines is in managing distributed, concurrent development, and that’s what this chapter is all about. You’ve done lots of great work on your machine, and now it’s time to push it back to your remote repository and synchronize what you’ve done with what’s on the server.

And there’s lots of reasons to have a remote repository somewhere, even if you are working on your own. If you ever need to restore your development environment, such as after a hard drive failure, or simply setting up another development machine, then all you have to do is clone your remote repository to your clean machine.

And just because you’re working on your own now doesn’t mean that you won’t always want to maintain this codebase yourself. Down the road, you may want another maintainer for your project, or you may want to fully open-source your code. Having a remote hosted repository makes doing that trivial.

Pushing your changes

So many things in Git, as in life, depends on your perspective. Git has perspective standards when synchronizing local repositories with remote ones: Pushing is the act of taking your local changes and putting them up on the server, while pulling is the act of pulling any changes on the server into your local cloned repository.

So you’re ready to push your changes, and that brings you to your next Git command, handily named git push.

Execute the following command to push your changes up to the server:

git push origin main

This tells Git to take the changes from the main branch and synchronize the remote repository (origin) with your changes. You’ll see output similar to the following:

Enumerating objects: 50, done.
Counting objects: 100% (46/46), done.
Delta compression using up to 16 threads
Compressing objects: 100% (31/31), done.
Writing objects: 100% (36/36), 3.39 KiB | 579.00 KiB/s, done.
Total 36 (delta 17), reused 2 (delta 1), pack-reused 0
remote: Resolving deltas: 100% (17/17), completed with 4 local objects.
To https://www.github.com/belangerc/ideas.git
   c470849..f5c54f0  main -> main

Git’s given you a lot of output in this message, but essentially it’s telling you some high-level information about what it’s done, here: It’s synchronized 17 changed items from your local repository on the remote repository.

Note: Wondering why Git didn’t prompt you for a commit message, here? That’s because a push is not really committing anything; what you’re doing is asking Git to take your changes and synchronize them onto the remote repository. You’re combining your commits with those already on the remote, not creating a new commit on top of what’s already on the remote.

Want to see the effect of your changes? Head over to the URL for your repository on GitHub. If you’ve forgotten what that is, you can find it in the output of your git push command. In my case, it’s https://www.github.com/belangerc/ideas, but yours will have a different username in there.

Once there, click the 26 commits link near the top of your page:

You’ll be taken to a list of all of your synchronized changes in your remote repository, and you should recognize the commits that you’ve made in your local repository:

That’s one half of the synchronization dance. And the yin to git push’s yang is, unsurprisingly. git pull.

Pulling changes

Pulling changes is pretty much the reverse scenario of pushing; Git takes the commits on the remote repo, and it integrates them all with your local commits.

Moving the remote ahead

First, you have to simulate someone else making a change on the remote. Navigate to the main page on GitHub for your repository: https://github.com/<username>/ideas. Once there, click on the tutorials directory link of your project, and then click on tutorial_ideas.md to view it in your browser.

[ ] Blockchains with BASIC
- [ ] Debugging with the Grace Hopper Method
git add books/book_ideas.md
git commit -m "Adding debugging book idea"
git push origin main
! [rejected]        main -> main (fetch first)
error: failed to push some refs to 'https://www.github.com/belangerc/ideas'
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 integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
git pull origin
Merge branch 'main' of https://github.com/belangerc/ideas into main
# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.
git log --oneline --graph
*   b495cc8 (HEAD -> main) Merge branch 'main' of https://github.com/belangerc/ideas
|\
| * 35054cc (origin/main, origin/HEAD) Update tutorial_ideas.md
* | 8648645 Adding debugging book idea
|/
*   a4eded5 Merge branch 'contact-details'
.
.
.

First step: Git fetch

git pull is really two commands in one: git fetch, followed by git merge.

ls .git
cat .git/FETCH_HEAD
8909ec5feb674be351d99f19c51a6981930ba285		branch 'main' of https://github.com/belangerc/ideas

Second step: Git merge

So once Git has fetched all of the commits to your local system, you’re essentially in a position in which you have a commit from one source — your local commit — that Git needs to combine with another commit: the remote commit. Sounds like merging a branch, doesn’t it?

| * 35054cc (origin/main, origin/HEAD) Update tutorial_ideas.md
* | 8648645 Adding debugging book idea
|/
*   a4eded5 Merge branch 'contact-details'
.
.
.
git push origin main

Dealing with multiple remotes

There’s another somewhat common synchronization scenario in which you have not one, but two remotes to deal with.

git remote add crispy8888 https://github.com/crispy8888/ideas.git
git remote -v
crispy8888	https://github.com/crispy8888/ideas.git (fetch)
crispy8888	https://github.com/crispy8888/ideas.git (push)
origin	https://www.github.com/belangerc/ideas (fetch)
origin	https://www.github.com/belangerc/ideas (push)
git log --oneline --graph --all
git fetch crispy8888
 * [new branch]      clickbait  -> crispy8888/clickbait
 * [new branch]      master     -> crispy8888/master
git log --oneline --graph --all
*   3ff6fbe Merge branch 'clickbait'
|\
| | * fbe86a2 (crispy8888/clickbait) Added another clickbait idea
| |/
| * e69a76a (origin/clickbait, clickbait) Adding suggestions from Mic
| * 5096c54 Adding first batch of clickbait ideas
| | *   22d9abd (crispy8888/master) Merge branch 'master' of https://github.com/crispy8888/ideas into master
| | |\
| | | * f550fed Update tutorial_ideas.md
| |_|/
|/| |
| | * f9278e6 Adding debugging book idea
| |/
|/|
git checkout clickbait
git merge crispy8888/clickbait
Updating e69a76a..9ff4582
Fast-forward
 articles/clickbait_ideas.md | 1 +
 1 file changed, 1 insertion(+)
* fbe86a2 (HEAD -> clickbait, crispy8888/clickbait) Added another clickbait idea
* e69a76a (origin/clickbait) Adding suggestions from Mic
* 5096c54 Adding first batch of clickbait ideas
git checkout main
git merge clickbait
*   72670be (HEAD -> main) Merge branch 'clickbait'
|\
| * fbe86a2 (crispy8888/clickbait, clickbait) Added another clickbait idea
* |   b495cc8 (origin/main, origin/HEAD) Merge branch 'main' of https://github.com/belangerc/ideas
|\ \
| * | 35054cc Update tutorial_ideas.md
* | | 8648645 Adding debugging book idea
|/ /
.
.
.
git push origin main

Key points

  • Git has two mechanisms for synchronization: pushing and pulling.
  • git push takes your local commits and synchronizes the remote repository with those commits.
  • git pull brings the commits from the remote repository and merges them with your local commits.
  • git pull is actually two commands in disguise: git fetch and git merge.
  • git fetch pulls all of the commits down from the remote repository to your local one.
  • git merge merges the commits from the remote into your local repository.
  • You can’t push to a remote that has any commits that you don’t have locally, and that Git can’t fast-forward merge.
  • You can pull commits from multiple remotes into your local repository and merge them as you would commits from any other branch or remote.

Where to go from here?

You’ve accomplished quite a bit, here, so now that you know how to work in a powerful fashion with Git repositories, it’s time to loop back around and answer two questions:

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2024 Kodeco Inc.

You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now