Working with a Remote Repository…

Till now we have been able to do the version control on our local machine and not share details with anybody. However, Git becomes more powerful when we collaborate with others using a remote server. This way other people can see them, download the changes that we made, to their local repositories, make their own changes and upload back to the remote server and this way we can download the changes to our local repositories. There is no real difference between a remote and a local repository. Like the local, it contains branches, commits and has a HEAD pointer. However, a local repository has a working directory where some version of our project’s files is checked out. Whereas a remote repository doesn’t have such a working directory: it only consists of the bare “.git” repository folder.

The Remote Server concept is pretty straightforward. As displayed below we have a Local Machine where we have a master branch with commits on it. Now we are going to introduce a Remote Server. We will move the commits from our master branch in local machine to the Remote Server using a process called Push. This means we push same commits from our Local Machine to the Remote Server. At the same time, Git also creates a new branch called origin/master on our local machine. This new branch always refers the Remote Server branch and tries to be in sync with the Remote Server.

Pictorial representation

As we continue our development and make further commits on our local machine and when we are ready to share, we push them to the Remote Server and the origin/master branch in our local machine also tries to in sync with the remote one. When other people push changes from their local machines to the Remote Repository, we can pull those changes down to our local machine using a process called Fetch. Notice that Fetch only updates the origin/master branch and it does not bring any updates to our master branch. To update in the master branch we need to do a merge and, at that point, the origin/master and the master branch will be in sync.

Now, in reality, Git is smart enough not to save same Git Objects twice as origin/master and master, instead, it uses two HEAD pointers pointing to same Git object.

Setting GitHub Account:

GitHub is a web-based version control Git repository service which is freely available. GitHub has paid plans too but for now, we will be using their free service.

    1. Our first task is to set up a GitHub account. To create an account, go to  GitHub website and complete the sign-up. Enter the username, email id, and password to complete the sign-up process.  Once sign up is complete, we have an option to continue as unlimited public repositories for free or select unlimited private repositories. Please note that using unlimited public repositories will allow everyone to view the project whereas using private repositories will allow only private parties to view the project. We will select the free version and click continue to complete the setup. Please note the UI may change over time but the sign-up should be pretty straightforward.
    2. Once sign-up is complete, our next step is to create a new repository. We can give any name to our repository. We will be using the same name from our Eclipse project. Once details are filled, click Create Repository button to create a new one.

      Create new repository in GitHub
    3. Once a new repository is created, we get 3 options – the first one is to create a new repository on the command line from our local machine. This we already completed, please refer Part 1: Working with Git…, the second one is to push an existing repository from the command line – here we will be using this option as we have an existing repository in our local machine, the third one is to import code from another repository. This we will not be using as we are using Git repository only. Notice the highlighted area. We will use this highlighted command to add a remote to our Local Machine.

      Repository options
    4. Our next task is to inform our repository in our Local Machine where it can find the remote repository. Switch over to the command line and navigate to our project folder. Type in commandgit remote to list out all the remotes that we have. Since we don’t have any remotes configured, the command will not list any remotes. To add a remote type in the command git remote add origin https://github.com/autotestmadness/HybridFramework.git. Please note that origin is the name of our remote. By default, the name is origin as displayed in above screenshot, however, we can use any name. The URL following is the location of the remote repository. After adding the remote if we use the command git remoteagain, it will list out all the remotes. Notice that origin is now added.

      Adding a Git remote
    5. Some additional commands:
      // To get more information on the URL to fetch and push
      git remote -v
      
      // To remove a particular remote
      git remote rm origin
      
      // To view remote details in config file
      cat .git/config
      
      // To view all remote branches
      git branch -r
      
      // To view all branches both local and remote
      git branch -a
      
    6. Our next step is to push our code to our remote repository. Type in command git push -u origin master. This command will push the code from our master branch to origin, which is the remote repository. To complete the process Git will ask for the GitHub username and password. Once the details are shared, it will compress and upload the code to the remote repository. Now as mentioned earlier, after pushing the code to the remote, Git will create a new branch name origin/master (refer the gif image for easy understanding). If we don’t use ‘-u‘ in our Git push code, Git will never be able to track the origin/master branch with the remote. So it’s always recommended to use ‘-u’ when doing our first push to remote.
      Pushing the code from master branch to remote

      Code pushed to the remote
    7. The new branch details can be found inside .git/refs/remotes/origin folder. Now if we use the command cat .git/refs/remotes/origin/master, we can see the SHA value of the last commit. This will be same as that of the master branch.

      origin/master branch details
    8. We can push more than one branch from our local machine to remote. For example, we can push one more branch named ‘mergebranch’, created in our last post Part 2: Working with Git… using the command git push origin mergebranch. Notice that this time we have not used ‘-u‘ in Git push command, as a result, origin/mergebranch will not be tracked to the remote. We can confirm by going to .git/config file. Notice (third screenshot) that there is a mapping between master (local) and origin/master (remote) as we used ‘-u‘ in our first push but there is no mapping between mergebranch (local) and origin/mergebranch (remote).
      origin/mergebranch created in remote
      mergebranch created in GitHub

      No mapping present for mergebranch
    9. In the last step, we learned how to push our local code into GitHub. This is useful when we are pushing code for the first time to GitHub. Now, what happens when there is already a project available on GitHub and we want to clone it into our local machine? In this step, we will clone the same project from GitHub and into the workspace present on our local machine. Notice that when cloning, tracking branch will be created by default. We can verify the mapping by viewing the .git/config file.
    10. To clone a project we will use the command git clone https://github.com/autotestmadness/HybridFramework.git ClonedHybridFramework. Notice that the command has the URL from GitHub and a name of the project directory on our local machine. If we are not using a name then by default a directory named ‘HybridFramework’ will be created. Since we already have a directory with the same name in our workspace, we will use a new name for the cloned project. Once the project is cloned, we can use the command ls -la to verify if everything is fetched from the remote.

      Cloning from GitHub
    11. Once we are inside the ‘ClonedHybridFramework’ folder, we can use the command git branch -a to list out both local and remote branches. Notice that in local we have only the master branch but in remote we have two branches – origin/master and origin/mergebranch.

      List of branches from local and remote
    12. Now we will simulate a scenario where two people will be collaborating with each other in GitHib. For that, we will use ‘HybridFramework’ and ‘ClonedHybridFramework’ directories. We will make changes in ‘HybridFramework’, commit our changes, and move the change to the remote. Then we will ensure that ‘ClonedHybridFramework’ gets the change. Even though both directories are on the same local machine, but repositories in both directories are different. Hence it will look like as if two different people are collaborating with each other.
    13. We will update the readme.txt file inside ‘HybridFramework’ folder and then commit the changes into the master branch. We follow the same process mentioned in our last post Part 1: Working with Git…. Notice that when we do git status after the commit in master branch in local, Git informs that the remote doesn’t have the latest commit.

      Updating readme.txt file in HybridFramework directory
    14. Next step is to push the last commit from ‘HybridFramework’ to the remote. Type in the command git push to push the changes to the remote. Since the origin/master branch is already mapped with the remote, we don’t have to use ‘-u’ in the command and also there is only one remote that is the origin, so we can simply use git pushcommand. Upon successful push, the GitHub will be updated with the latest commit.

      Latest commit updated into GitHub
    15. Now let’s switch to the ‘ClonedHybridFramework’ directory. If we do a git log --oneline origin/master -3, we will not see the latest commit in ‘ClonedHybridFramework’ directory. It doesn’t exist in origin/master or in master.  To reflect the changes in origin/master, we will have to Fetch the changes into ‘ClonedHybridFramework’ directory. Notice that after Fetch, the changes exist in origin/master branch but not in the master branch.

      git fetch to update in origin/master branch
    16. Our next task is to sync up the master branch with that of origin/master branch in the ‘ClonedHybridFramework’ directory. To sync up, we have to merge the changes from origin/master branch to master branch. The merging process is exactly same that we learned in our last post Part 2: Working with Git….
    17. To merge into master, ensure that we are in master branch and then type in the command git merge origin/master. Notice that this is a Fast-Forward merge as we did not do any changes in the master branch.

      merge the changes from origin/master to master
    18. If we do a git log now in both branches, we can view the latest commit in both master and origin/master.

      Latest commit available in master branch
    19. Its always recommended to do a Fetch first and Fetch often, then Merge, and then Push the changes to the remote.
    20. There is a very convenient command git pull which is actually a combination of Git Fetch and Git Merge. This single command will first complete the Fetch process and then do a Merge.
    21. As we have seen, we only have master branch checked out in ‘ClonedHybridFramework’ directory. What if we want to check out ‘mergebranch’ also from the remote? We can checkout using the command git branch mergebranch origin/mergebranch. Here we are creating a new branch named ‘mergebranch’ in local which is tracked to remote branch ‘origin/mergebranch’. To checkout the new branch directly, we can use the command git checkout -b mergebranch origin/mergebranch.

      Remote branch is checked out
    22. We can verify the mapping by viewing the .git/config file inside ‘ClonedHybridFramework’ directory.

      .git/config file with tracking details

 

With this, we came to end on remote repository topic. Hope you were able to follow most of it. Until next post, Happy Learning!