I have used the open source enterprise search platform Solr for a number of years now and on a recent project have been using the open source SolrNet .NET client library. The SolrNet library lacked a feature I required when used with the bundled Service Locator implementation. A number of people had been asking for the same feature so I decided to jump in and implement it.
This is part 3 of my journey into learning Git, using GitHub and contributing to an open source project.
Configure Git Options
Since I was about to fork a project and start dealing with code it seems like a good time to configure my identity within Git. Git uses your name and email address to sign your commits.
This can be achieved via the Git Bash shell by typing the following commands:
git config --global user.name "your_full_name"
git config --global user.email "your_email_address"
The global switch applies this information to all of your projects. If you would like to override options for a particular project leave out the –global switch when in that project.
The following command will list out all your configured options:
git config --list
The typical workflow of contributors to an open source project hosted on GitHub can be a bit intimidating. It involves the following steps:
- Write and commit code
- Submit pull request
I’ll discuss the first two steps (fork, clone) in this post and will cover the remainder in the next two posts.
Forking the SolrNet Project
The SolrNet project was created by Mauricio Scheffer and is hosted on GitHub at https://github.com/mausch/SolrNet.
To contribute code to a project on GitHub typically starts with you having to fork the project. Forking the project creates a copy of the master repository with a complete history under your GitHub account. This is great since it allows you to start contributing code and have the changes publically available to anyone who wants them – you don’t need commit access to the master project.
I navigated to the master project mausch/SolrNet page and clicked on the Fork button.
GitHub managed the forking of the master project and created a forked copy for me. It is now available at https://github.com/paulbouwer/SolrNet. GitHub also clearly shows that the project has been forked from the original project mausch/SolrNet.
Git is a distributed version control system which allows greater flexibility in how developers contribute and collaborate on projects. I don’t have commit access to the master repository mausch/SolrNet so GitHub helped me fork the repository to create a public repository paulbouwer/SolrNet to which I have read/commit access. So now I can commit changes into my paulbouwer/SolrNet repository and Mauricio can pull any of my commits into the master mausch/SolrNet repository (if he wants them).
Cloning your GitHub repository
A typical and common workflow in Git is to have a private local copy of your public repository. This allows you to have a working space that is under revision control. Once you are happy with the changes you have implemented you can roll them up into a single commit to your public repository and ask the maintainer of the master project to pull your commit into the master repository.
Obtaining a private local copy of your public repository is achieved using the git clone command. As the name suggests this is a clone of the repository (as opposed to a checkout in SVN). The cloned repository contains its own copy of the entire history of the project.
First we need the public repository URL from GitHub. I was having some firewall issues with SSH so decided to use my HTTP URL.
I ran the git clone command from the C:\Projects\GitHub folder via Git Bash shell. When prompted for a password enter the key passphrase for the SSH key registered with GitHub.
git clone https://firstname.lastname@example.org/paulbouwer/SolrNet.git
This successfully cloned my public paulbouwer/SolrNet repository into my C:\Projects\GitHub\SolrNet folder as can be seen above. You can also see that the master branch is the active branch at the moment.
You can also clone a repository via TortoiseGit by clicking on Git Clone … on the right click context menu in Windows Explorer in the C:\Projects\GitHub folder.
After providing your SSH key passphrase TortoiseGit will begin the clone.
TortoiseGit has successfully cloned my public paulbouwer/SolrNet repository into my C:\Projects\GitHub\SolrNet folder as can be seen above. This is missing some of the contextual information we saw in the Git Bash shell such as the current active branch. I prefer using the Git Bash shell as it gives me more information and finer grained control. I will continue purely with the Git Bash shell for the rest of this series of posts.
Now that I have a local copy of my repository I need a mechanism to manage changes between it and my public repository paulbouwer/SolrNet. I also need to manage changes between my local repository and the master repository mausch/SolrNet. This is achieved using the remotes concept in Git.
From the Working with Remotes section of the Pro Git book:
Remote repositories are versions of your project that are hosted on the Internet or network somewhere. You can have several of them, each of which generally is either read-only or read/write for you. Collaborating with others involves managing these remote repositories and pushing and pulling data to and from them when you need to share work
I obtained the HTTP URL of the master repository mausch/SolrNet.
I added a link to the master repository using the git remote command via the Git Bash shell. I used the typical remote name of upstream to denote the master repository mausch/SolrNet. I used the git remote command to also verify that the remote was added correctly.
git remote add upstream https://github.com/mausch/SolrNet.git
git remote –v
The remote link to the master repository has been successfully added under the name upstream. But what is that remote named origin and how did it get added? When you clone a repository, Git automatically adds a remote to the repository you have cloned with the name of origin.
I then ran the git fetch command via the Git Bash shell. This fetches any changes from my upstream remote and pulls them down into my local repository. I did not do this for my origin remote since I know that I have just cloned my local repository from it.
git fetch upstream
The git fetch command fetches changes across all the available branches.
The final step is now to run the git merge command via the Git Bash shell. This will merge the fetched upstream changes into my local repository.
git merge upstream/master
I was only concerned about the master branch changes and therefore that is all that I merged in from the upstream fetch. You can also see that since I had just forked my public repository and cloned my local repository from that there were no changes to merge in.
Now I have a public repository that I can use for pull requests and an up to date local repository that is ready for me to start coding in. Next is writing some code …