Git is a powerful tool. You can commit saved work never to be lost again, branch and merge with ease, and manage source code changes without a care in the world. And all this from your local machine without so much as a 14.4k modem. But what if you want to share your work or build off of some else’s? This is where remoting comes in.
Remoting involves the management of remote repositories and syncing of code to be in line with your own. Remoting is not about directly working with code in a remote repository however. Rather, it is usually involves the movement of code to your local machine where it is then managed and pushed back to a publicly-accessible repository.
The first step is retrieving code from the public repository. If you’re just creating your project this is done by using the clone command:
git clone remoteUri localRepo
This command will pull all commits from the repository remoteUri and recreate them in a repository named localRepo on your local machine. What it also does is store that remoteUri under an alias (origin by default) so that you can put code back in the remote repository later. You can register other remote repositories for your repo by using the add flag for the remote command:
git remote add alias remoteUri
Here, alias is the short name for the uri (origin, remote-master, it can be anything!) and remoteUri is once again the location of the remote repo. These aliases will be used when moving code to and from the repository. You can verify that the repository was entered by specifying the -v flag on the remote command:
git remote -v
Ah yes, moving code around. You can bring code to your machine by using the pull or fetch commands. Both are similar, though pull will perform an automatic merge while fetch will not. The following command sets are equivalent:
git pull origin branchName
git fetch origin
git merge origin/branchName
Either of the above will bring code into your current working copy and merge the contents with your work. After putting your two cents in and fixing bugs or adding (undocumented) features it’s time to put the code back into the public repository using the push command:
git push origin
There we go, simple simple. Why bring the code to the local machine though, why not just work off the remote repo directly? A few days ago I tried this:
git checkout origin/master
I though “I’ll just work off a remote branch, fix a bug and commit my changes without having to push/pull”. Here’s where I learned the true nature of a branch. A branch is simply a pointer to a commit (with a commit being an accumulation of the changes, or a diff, since the last commit). A commit also contains a record to the commit before it, building a chain of changes that allow for the determination of a file’s contents. The thing about pointers is… they’re only local! By checking out a remote branch I began working in what git warned me was a detached HEAD state, which meant that my changes were effectively being written off somewhere in space with no knowledge of what commit on your local machine to use as the basis for the next commit (somewhere on a remote machine was anyone’s guess).
Now git is great and user friendly but if you ignore the 10-line warning message like I did you may put in lots of time, commit your work, change branches and then wonder where your work went. Even though the changes won’t be reflected in any of your named branches, git never eats commited code. Every commit results in a hash code key to act as the identifier for that commit. All you have to do is use the hash code as the branch name (“git checkout 123ea4123a3aef8bd87ae”).
But who wants to type in THAT each time. Since branches are just pointers to these commits, you can create a branch on that commit and then can reference it much easier:
git checkout 123ea4123a3aef8bd87ae
git branch rescuedBranch
From here we can either continue to work on it like a normal branch or merge it back to another branch on your local machine. How to get this hash code though? Simple, we go through git’s logs. If you are still on the detached branch, simply call the reflog command to retrieve a list of recent commits and their hashes:
git reflog
If you committed and then switched to another branch it will take a little bit more work. The log command outputs a history of commits made and if you specify the –all option you can see everything. For some extra flair, the –graph option outputs a graph showing the various branches and merges that occurred as well:
git log --all --graph
Like any good Linux-inspired tool, git work great with other utilities such as grep if you know a bit more information about the commit like the Date, commit messages or Author. For an explanation of that though, I’ll defer to a git professional.