Skip to content

bobby_dreamer

Git Theory - 6 - Remote repository

notes, git5 min read

One of the best feature about GIT Source Control Management(SCM) is its distributed. Git repositories can be hosted in a file server in the web which can be your backup (or) a repository you are contributing to (or) someone else is contributing to yours.

To collaborate in any project in the current world, zipping your development folder and sending it over an email (or) sharing the zip via any file sharing platforms is unacceptable. You need to know how distributed SCM system works.

Good news is, git is a distributed SCM, so you just need to know how to manage your remote repositories which basically involves setting up remote repositories, cloning, push, pull and handling conflicts.

# Setting up remote repository

This is the syntax to add a remote git repository git remote add <shortname> <url>

When you try to create a git repository in Github by default it will ask you run few git commands like below,

If you are setting up a new repository with name bootstrap5alpha2. You can run the below commands in your local system and notice git remote add command with origin(is just a short name for your remote) and url. Here main is the new master branch, default branch name has been changed.

1# …or create a new repository on the command line
2echo "# bootstrap5alpha2" >> README.md
3git init
4git add README.md
5git commit -m "first commit"
6git branch -M main
7git remote add origin https://github.com/bobbydreamer/bootstrap5alpha2.git
8git push -u origin main

If you already have the repository 'bootstrap5alpha2' in your local system and you want to just upload it to remote then you can do the below,

1# …or push an existing repository from the command line
2git remote add origin https://github.com/bobbydreamer/bootstrap5alpha2.git
3git branch -M main
4git push -u origin main #or use this if github just has initial commit : git push --force -u origin main
  • git push -u origin new-feature : -u or --set-upstream flag adds the new branch new-feature to the upstream(tracking) reference, so next time git push can be invoked without any parameters to automatically push the new-feature branch to the central repository.

# Clone

Cloning a repository automatically downloads all the data from that repository including its history and git makes local master branch as a tracking branch for the master branch of the origin repository (short: origin/master ) by Git.

If tracking branches need to be created manually, you need to run below commands

1git checkout -b newbranch origin/new-feature
2
3# (or)
4
5# create branch based on remote branch
6git branch new-feature origin/master
7git branch --track new-feature origin/master

So, if remote repository is updated with new developments after you cloned, you can do a git fetch and download all the latest data but does not merge that data with your current working directory. Thats the job for git pull, it does all the merging automatically.

Github - Clone

In the below git clone command, i have used '.' to initialize current folder as a git repository and if i have not done that, in that case, git clone command would have created a new folder 'HelloWorld` and git initialized that.

1Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3
2$ git clone https://github.com/bobbydreamer/HelloWorld.git .
3Cloning into '.'...
4remote: Enumerating objects: 74, done.
5remote: Total 74 (delta 0), reused 0 (delta 0), pack-reused 74
6Unpacking objects: 100% (74/74), done.

git remote with -v shows the remote details(remote name, url)

1Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master)
2$ git remote -v
3origin https://github.com/bobbydreamer/HelloWorld.git (fetch)
4origin https://github.com/bobbydreamer/HelloWorld.git (push)
5
6Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master)
7$ git remote show
8origin
9
10Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master)
11$ git branch
12* master
13
14Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master)
15$ git branch -a
16* master
17 remotes/origin/HEAD -> origin/master
18 remotes/origin/master
19
20Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master)
21$ git remote show origin
22* remote origin
23 Fetch URL: https://github.com/bobbydreamer/HelloWorld.git
24 Push URL: https://github.com/bobbydreamer/HelloWorld.git
25 HEAD branch: master
26 Remote branch:
27 master tracked
28 Local branch configured for 'git pull':
29 master merges with remote master
30 Local ref configured for 'git push':
31 master pushes to master (up to date)

# Push

If you want to share your code changes or back it up, you have to do git push which basically uploads all your committed data to your remote repository.

1Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master)
2$ cat readme.MD
3# Push Testing
4Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master)
5$ git add .
6
7Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master)
8$ git commit -m "Push Testing"
9[master f1db835] Push Testing
10 1 file changed, 1 insertion(+), 2 deletions(-)
11
12Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master)
13$ git push origin master
14Counting objects: 3, done.
15Delta compression using up to 8 threads.
16Compressing objects: 100% (2/2), done.
17Writing objects: 100% (3/3), 285 bytes | 285.00 KiB/s, done.
18Total 3 (delta 1), reused 0 (delta 0)
19remote: Resolving deltas: 100% (1/1), completed with 1 local object.
20To https://github.com/bobbydreamer/HelloWorld.git
21 d33855d..f1db835 master -> master

Github - Push Testing

Push tags using below command

1git push --tags

# Pull

git fetch command will fetch all the changes on the server that you don’t have yet, it will not modify your working directory at all. It will simply get the data for you and let you merge it yourself. However, there is a command called git pull which is essentially a git fetch immediately followed by a git merge.

What git pull does is, it will look up what server and branch your current branch is tracking, fetch from that server and then try to merge in that remote branch.

Now, i have updated the readme.MD directly at git as 'Pull Testing' and currently local system is not aware of the new changes.

Github - Pull Testing

1Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master)
2$ git lol -n 3
3* f1db835 - (HEAD -> master, origin/master, origin/HEAD) Push Testing (6 minutes ago) <Sushanth Bobby Lloyds>
4* d33855d - 13. Updating readme.md (2 years, 8 months ago) <Sushanth Bobby Lloyds>
5* aac86ea - 12. Adding readme.md (2 years, 8 months ago) <Sushanth Bobby Lloyds>

There is no easy porcelain command to see if there are any latest commits at remote. Below is one of the approaches.

1Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master)
2$ git ls-remote https://github.com/bobbydreamer/HelloWorld.git
3311577e12ae8b60fe1b3ef9abf6580922a2c3c13 HEAD
4311577e12ae8b60fe1b3ef9abf6580922a2c3c13 refs/heads/master

Every other commands gets data from local only like below and after git fetch they can show the remote commits.

1Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master)
2$ git rev-parse origin/master
3f1db83597d8adba36d22262644c0381c36e59564
4
5Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master)
6$ git rev-parse HEAD
7f1db83597d8adba36d22262644c0381c36e59564

First we will try git pull then we will do another update and try git fetch

1Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master)
2$ git pull -at
3remote: Enumerating objects: 5, done.
4remote: Counting objects: 100% (5/5), done.
5remote: Compressing objects: 100% (2/2), done.
6remote: Total 3 (delta 1), reused 0 (delta 0), pack-reused 0
7Unpacking objects: 100% (3/3), done.
8From https://github.com/bobbydreamer/HelloWorld
9 f1db835..311577e master -> origin/master
10Updating f1db835..311577e
11Fast-forward
12 readme.MD | 2 +-
13 1 file changed, 1 insertion(+), 1 deletion(-)
14
15Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master)
16$ git lol
17* 311577e - (HEAD -> master, origin/master, origin/HEAD) Pull Testing (37 minutes ago) <Sushanth Bobby Lloyds>
18* f1db835 - Push Testing (39 minutes ago) <Sushanth Bobby Lloyds>
19* d33855d - 13. Updating readme.md (2 years, 8 months ago) <Sushanth Bobby Lloyds>
20* aac86ea - 12. Adding readme.md (2 years, 8 months ago) <Sushanth Bobby Lloyds>

Now again we have updated readme.MD in github and this time try to fetch.

Github - Fetch

1Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master)
2$ git lol -n 3
3* 311577e - (HEAD -> master, origin/master, origin/HEAD) Pull Testing (40 minutes ago) <Sushanth Bobby Lloyds>
4* f1db835 - Push Testing (41 minutes ago) <Sushanth Bobby Lloyds>
5* d33855d - 13. Updating readme.md (2 years, 8 months ago) <Sushanth Bobby Lloyds>
6
7Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master)
8$ git ls-remote https://github.com/bobbydreamer/HelloWorld.git
95f2670d5823af2977a0bdbe8df08dfa6aae36bd7 HEAD
105f2670d5823af2977a0bdbe8df08dfa6aae36bd7 refs/heads/master
11
12Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master)
13$ git branch -vv
14* master 311577e [origin/master] Pull Testing
15
16Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master)
17$ git fetch --all
18Fetching origin
19remote: Enumerating objects: 5, done.
20remote: Counting objects: 100% (5/5), done.
21remote: Compressing objects: 100% (2/2), done.
22remote: Total 3 (delta 1), reused 0 (delta 0), pack-reused 0
23Unpacking objects: 100% (3/3), done.
24From https://github.com/bobbydreamer/HelloWorld
25 311577e..5f2670d master -> origin/master
26
27Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master)
28$ git branch -vv
29* master 311577e [origin/master: behind 1] Pull Testing

Since its fetched, now you can do git merge

1Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master)
2$ git merge origin/master
3Updating 311577e..5f2670d
4Fast-forward
5 readme.MD | 2 +-
6 1 file changed, 1 insertion(+), 1 deletion(-)
7
8Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master)
9$ git lol -n 3
10* 5f2670d - (HEAD -> master, origin/master, origin/HEAD) Fetch Testing (10 minutes ago) <Sushanth Bobby Lloyds>
11* 311577e - Pull Testing (49 minutes ago) <Sushanth Bobby Lloyds>
12* f1db835 - Push Testing (50 minutes ago) <Sushanth Bobby Lloyds>
Fetch from all remote repositories

The git fetch command updates only the remote-tracking branches for one remote repository. In case you want to update the remote-tracking branches of all your remote repositories you can use the following command.

1# this runs git fetch for every remote repository
2git remote update
3
4# the same but remove all stale branches which are not in the remote anymore
5git remote update --prune

# Deleting Remote Branches

When all your developments on a feature is done. You can delete the remote branch.

1git push origin --delete FeatureBranch007

# Renaming remote branch

1Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master)
2$ git remote rename origin rem-HW
3
4Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master)
5$ git remote -v
6rem-HW https://github.com/bobbydreamer/HelloWorld.git (fetch)
7rem-HW https://github.com/bobbydreamer/HelloWorld.git (push)

# Deleting remote branch

1Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master)
2$ git remote remove rem-HW
3
4Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master)
5$ git remote -v

# Forking

Forking is a popular workflow, mostly used in open-source projects. Fork operation clones the remote repository to your github/BitBucket account instead of downloadig it your local computer. Forked repositories are special they just git clone on the server-side maintained by GH/BB. Later you can clone the personalized copy of that repository to your local system.

Below is the process when creating a fork Github - Fork

Forking workflow mostly would be following below steps,

  1. Do a fork in GitHub or BitBucket on any project which you want to contribute to, it could be an open source project as well.
  2. Once you get the personalized copy that open-source repository to your account, clone it to your local. This forked repository becomes the origin, remote is automatically added by git clone which you can check by git remote -v.
  3. Go to the original open-source repository which you wanted contribute to and get the URL by clicking the clone drop-down. Come back to your local machine and do git remote add upstream URL, this will add that official open-source repository as upstream.
    • Basically forked repos have two remotes
      • Origin which points to personalized copy of the forked repo
      • Upstream, points to the offical open-source repository
        • Upstream is setup, so that you can regularly pull the latest changes
      • In the end when you do git remote -v you should two entires for origin and two rows for upstream.
  4. Create a local branch and work on it and when it looks good, commit it.
  5. Periodcally check the offical repository for any new updates and pull using
    1git pull upstream master
    2# or
    3git fetch upstream
    4git checkout master
    5git merge upstream/master
  6. Push the changes to your personalized copy of the open-source repository.
    • git push origin feature-branch
  7. Go to github, you should see Compare & pull request button, click it to begin a Pull Request(PR) from the new branch to the 'official open-source' repository. In the pull request, you will see that orginal open-source repository is listed as the "base repository", and your fork is listed as the "head repository". Before submitting the PR, you need to describe the change you have made.
  8. The maintainer might ask you to make some changes you can do by,
    • Go to your local feature-branch
    • Make updates and commit
    • Push changes to your fork
    • Open your pull request, you should see your new commits.
    • Discuss on the changes in comments and resolve conversation.
  9. PR get reviewed by the maintainer and when all good, gets approved for merge to the main open source project repository. You will be given an option to delete your branch, you can proceed to do so, if you wish. If you delete the branch, you should delete it in your local as well. git branch -D feature-branch
  10. Synchronize your fork by running below commands and after that go to Github to your fork, you should see a message like "This branch is even with open-source repository". This step is not necessary but it keeps thing clean.
    1git pull upstream master
    2git push origin master

Below is the process when submitting a pull request, Github - Fork

On the other side what the maintainer does to integrate is,

  1. Maintainer pulls the contributor’s changes into his/her own local repository
  2. Reviews to to make sure it doesn’t break the project and then merges it into their local master branch
  3. Pushes the master branch to the official repository on the server.

Now this contribution is now part of the bigger project and other developers should pull from the official repository to synchronize their local repositories.


# Next steps

  • Git Everyday : Git flowchart, shortcuts and references
  • Origin : How it all began. What is git ? and Terminologies used in this series.
  • Basics : config, init, add, rm, .gitignore, commit, log, blame, diff, tag, describe, show and stash
  • Undos : checkout, reset, revert and restore
  • Branching : Git Branching
  • Internals : Git Internals