While there are dozens of get-started guides for Git and users of GitHub see a "pro tip" every time they refresh GitHub.com, it's still not easy to find a collection of useful tips for developers who want to work smarter with Git and GitHub. Let's fix that.
For those of you who are unfamiliar with Git or GitHub, the next few paragraphs will give you enough background to understand the tips.
Git is a distributed version control system, originally written by Linus Torvalds in 2005 for and with help from the Linux kernel community. I'm not here to sell you on Git, so I'll spare you the spiel about how fast and small and flexible and popular it is, but you should know that when you clone a Git repository ("repo," for short), you get the entire version history on your own computer, not just a snapshot from one branch at one time.
Git started as a command-line tool, befitting its origin in the Linux kernel community. You can still use the Git command line, if you like, but you don't have to. In particular, if you use GitHub as your host, you can use the free GitHub client on Windows or Mac. On the other hand, the Git command line will work for any host, and it comes pre-installed on most Mac and Linux systems.
Only you can decide whether you are most comfortable using the command line or a native client with a graphical user interface. If you like a GUI, in addition to the GitHub client (Windows and Mac), you might want to consider SourceTree (Windows and Mac, free), TortoiseGit (Windows only, free), and Gitbox (Mac only, $14.99). Or you can use an editor or IDE that supports Git internally (see tip No. 11).
Git/GitHub tip No. 1: Clone almost anything
There are many interesting projects available from GitHub and other public Git repositories that you can clone freely to your own computer. Why would you want to do that? One reason is to learn something about coding style, practice, and tools in a language of interest, including commit log commenting style (see tip No. 4). A second reason is to learn how a given project accomplishes its goals. A third reason, should the licensing both permit you to do so and make sense for your purposes, would be to incorporate the project into your own endeavor or product. Double-check the license, by the way, so that you don't run into compliance issues later on.
The definition of
git clone from the manual page:
Clones a repository into a newly created directory, creates remote-tracking branches for each branch in the cloned repository (visible using
git branch -r), and creates and checks out an initial branch that is forked from the cloned repository's currently active branch.
After the clone, a plain
git fetchwithout arguments will update all the remote-tracking branches, and a
git pullwithout arguments will in addition merge the remote master branch into the current master branch, if any.
Git/GitHub tip No. 2: Pull frequently
One of the easiest ways to make a mess for yourself with Git (and indeed, with any version control system) is to allow files to get out of sync. If you
git pull frequently, you will keep your copy of the repo up to date, and you will have the opportunity to merge your changed code with others' changes while the merging is easy to understand and accomplish -- ideally, when it's so easy that it can be done automatically. A corollary of this tip is to watch your project status. Many Git clients will automatically show you when you need to update to stay current.
Git/GitHub tip No. 3: Commit early and often
A commit is a granular update to a project, which includes one or more changes to one or more files. Think of it as a record of a unit of work completed, which can be applied to or removed from the project as a logical whole. Do commit every logical change you complete, even before testing it. Commits only apply to your local repository. See tips No. 4 and 5 for corollaries to this tip.
The definition of
git commit from the manual page:
Stores the current contents of the index in a new commit along with a log message from the user describing the changes.
Git/GitHub tip No. 4: Comment your commits as you would have others comment theirs
There are 10 kinds of coders: Those who comment their commits, and those who don't. (Old joke. Hint: What base am I using?)
I freely admit to being a stickler for good commit log messages. I set up my repositories to require messages for every commit, and I've been known to send out annoyed late-night messages when commits land with logs on the order of "xx." If you're the kind of developer who thinks (1) the code should speak for itself and (2) the in-line comments are way more important than the change logs, try cloning a repository you've never seen before and identifying the recent commit that may have caused the latest issue posted without reading all the code. As you can see, accurate commit logs are double-plus good.
Git/GitHub tip No. 5: Push when your changes are tested
The worst Git-related bug I've ever had the misfortune to know about happened when an outsourcing company switched from Subversion but didn't train its developers on the difference between distributed source control and centralized source control. About a month later, the project developed weird bugs that nobody could seem to track down. At the daily stand-up meetings, the developers responsible for the area of the application that was misbehaving would protest, "I fixed that two weeks ago!" or accuse another developer of not bothering to pull the changes they had so carefully checked in.
Eventually, someone identified the problem and taught all the developers how and when to
push their commits: In short, whenever the commits test successfully in a local build. Then the company did a two-day-long merge fest before being able to build and deploy the updated, integrated product.
Git/GitHub tip No. 6: Branch freely
One of the biggest advantages Git has over some other version-control systems is that merging usually works well, at least partly because Git automatically chooses the best common ancestor to use for a merge. Most software developers need to start creating branches in their projects more often. It should be a routine daily occurrence, not the subject of an anguished all-hands strategy meeting. The likelihood is that, when the branch project is complete, accepted, and ready to move into the main project, the merge will not present any insurmountable problems.
I know that takes some adjustment, especially if you've been stuck in a company that does source code control with CVS. But try it. It's a whole lot better than having customers accidentally see your unfinished experimental code when the trunk project has to be published because of a breaking bug. (This article explains basic branching and merging well.)
Git/GitHub tip No. 7: Merge carefully
While merges with Git usually work well, if you do them without thinking, you can occasionally encounter difficulty. Step one is to make sure you have no uncommitted changes. From the
git merge manual page:
Before applying outside changes, you should get your own work in good shape and committed locally, so it will not be clobbered if there are conflicts. See also
Also see tip No. 8.
Even if it all goes south during a
git merge, you aren't hosed:
If you tried a merge which resulted in complex conflicts and want to start over, you can recover with
git merge --abort.
The follow-on command to
git merge is usually
git mergetool, assuming you like to use a GUI for merging. If you'd prefer the old-school method, you can edit the files in conflict with your favorite programming editor, fully remove the
>>>>>>> lines, save the revised files, and
git add each file you fixed.
Git/GitHub tip No. 8: Stash before switching branches
A software developer's workflow is rarely linear. Users have the gall to report bugs, managers have the audacity to prioritize tickets other than the one you picked to work on, and you yourself might change your mind about what you want to do.
There you are, with three files committed for a release, and a fourth file in a changed but non-working state. (The
git status command will tell you all of this if you don't happen to remember where you were.) All of a sudden you need to work on a bug fix in a production version. You need to switch branches pronto, but you can't. Your working directory is dirty and you have two hours of work you don't want to lose.
git stash. Voilà! Now you have all your changes stored in a WIP (work in progress) branch, and you can switch to the production branch from your clean directory. When you're done with that, switch back to where you were with
git stash apply.
Git/GitHub tip No. 9: Use gists to share snippets and pastes
GitHub "gists" -- shared code snippets -- are not a Git feature, but they use Git. All gists are Git repositories, andGitHub Gist makes it easy to share them. You can search Gist for public gists by topic, programming language, forked status, and starred status. You can also create secret gists and share them by URL.
Git/GitHub tip No. 10: Explore GitHub
Many interesting open source projects have repositories on GitHub. Explore GitHub provides a browsing interface to find some of them, but mostly it's easier to type a few letters of the project's name in the search box to find its repos. For example, type
Git/GitHub tip No. 11: Contribute to open source projects
As long as you're browsing open source projects, why not contribute to them? It isn't as hard as you might think, and you'll learn a lot. For example, you could clone the jquery/jquery (jQuery Core) project, and browse through README.MD. Near the top you'll see:
In the spirit of open source software development, jQuery always encourages community code contribution. To help you get started and before you jump into writing code, be sure to read these important contribution guidelines thoroughly...
That's followed by three links. The first of the three will get you started fairly quickly. Not every open source project lays out the plan so clearly, but they all try.
Understand the difference between being a contributor and a committer. A contributor has signed the required agreements and made a contribution available to the project. A committer is empowered to actually commit the proffered contribution to the project repository. Because there will be a delay while a committer tests your contribution and you won't want to tie up your master branch, you should make your changes in another branch (see tip No. 6) before sending out a pull request (see tip No. 16).
Git/GitHub tip No. 12: Use editors and IDEs that "git it"
If you're barreling along on an edit only to discover, when you go to check it in, that someone else has been working on the same code as you have, you're likely to become frustrated. You can avoid or at least minimize that frustration by using an editor or IDE that integrates Git and actually tells you that the code you're viewing has new commits that you should pull, and what the new commits are supposed to accomplish.
Git/GitHub tip No. 13: Fork a repo
Forking a repository means creating your own writable server copy of a repo -- that is, creating a fork in the road. Recall that we clone a repo (see tip No. 1) to make our own client copy of it. If it's a public repo for which we do not have commit privileges (see tip No. 11), then the easiest way to contribute our changes is to first commit them to our own fork of the repo on the server via the fork button on the original GitHub project. Then we can issue a pull request (see tip No. 16) to the owners of the forked repo so that they can test and possibly use our contribution. It's confusing at first, but it gets easier. See, for instance, this book section on contributing to a small public project.
Git/GitHub tip No. 14: Watch projects
When you fork a project, you'll most likely want to know what's happening in the upstream project. If so, watch the repo. If the update chatter annoys you, unwatch it. If you notice changes that affect you, fetch and merge the upstream commits.
Git/GitHub tip No. 15: Follow friends
GitHub suggests that you follow GitHub employees "in a non-creepy way." You should also follow people from projects that interest you, and that might lead you to other projects that interest you. I followed dmethvin on GitHub -- but that's not creepy since we've worked together on and off since he was at PC Tech Journal, and now he's president of the jQuery Foundation.
Git/GitHub tip No. 16: Send pull requests
In tip No. 13, we talked about forking a GitHub repository. The way to get the upstream repository (the one you forked from to make yours) to incorporate some or all of your changes is to send them a pull request, following this guide.
Git/GitHub tip No. 17: Create and resolve issues
All software has bugs. Many software projects use a separate bug-tracking system, but some use the Issues feature in GitHub. You can be useful to a project by reporting an issue, and even more useful by solving one.
Git/GitHub tip No. 18: Write informative README pages
In tip No. 11, I sent you to the README page of jquery/jquery to find out about the project. Write good README pages for your projects, and you won't regret it.
README has been an established convention in software development since at least the 1960s, when I saw my first one printed out IN ALL CAPS on the green-and-white paper that was wrapping a stack of Hollerith cards intended to be run on an IBM 1640. I saw many more in the 1970s, on every conceivable media and operating system, when I worked on DEC minicomputers and large IBM mainframes. See alsoREAMDE.
Git/GitHub tip No. 19: Use Markdown
Early README files IN ALL CAPS were more than a little basic. The current standard for formatting README files isMarkdown, specifically GitHub Flavored Markdown. I used to see README files in HTML, but the practice seems to be fading.
Git/GitHub tip No. 20: Convert your older repos to Git
Of all the tips I've listed, this one might be the hardest to implement, both technically and politically. Politically it's hard because programmers are by nature conservative about their tools. That needs to be addressed with training (see tip No. 5).
It's technically hard to convert big, old repositories with millions of lines of code, tens of thousands of commits, and thousands of tags because the processes for this use a metric ton of memory. I have had decade-old CVS repositories that would only convert on large or extralarge Amazon EC2 instances, and they still took days for the conversion to complete. If you're converting from Subversion, try using svn2git. If you're converting from CVS, consider
git -cvsimport and cvs2git.